mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 13:11:39 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
+16
@@ -0,0 +1,16 @@
|
||||
<component name="libraryTable">
|
||||
<library name="assertJ">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-core-2.1.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-guava-2.0.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-core-2.1.0-javadoc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-guava-2.0.0-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-core-2.1.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/assertj-guava-2.0.0-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
Generated
+4
-4
@@ -1,10 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="fest">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-assert-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-reflect-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-swing-1.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-util-1.1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-assert-1.5.0-SNAPSHOT.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-reflect-2.0-SNAPSHOT.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-swing-1.4-SNAPSHOT.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/android/android/lib/fest-util-1.3.0-SNAPSHOT.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
|
||||
Generated
+5
@@ -30,8 +30,11 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/boot/boot.iml" filepath="$PROJECT_DIR$/platform/boot/boot.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" filepath="$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/build-system/builder-model/builder-model.iml" filepath="$PROJECT_DIR$/android/tools-base/build-system/builder-model/builder-model.iml" group="android/sdktools" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/build-system/builder-test-api/builder-test-api.iml" filepath="$PROJECT_DIR$/android/tools-base/build-system/builder-test-api/builder-test-api.iml" group="android/sdktools" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/built-in-server/built-in-server.iml" filepath="$PROJECT_DIR$/platform/built-in-server/built-in-server.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/built-in-server-api/built-in-server-api.iml" filepath="$PROJECT_DIR$/platform/built-in-server-api/built-in-server-api.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/chartlib/chartlib.iml" filepath="$PROJECT_DIR$/android/tools-base/chartlib/chartlib.iml" group="android/sdktools" />
|
||||
<module fileurl="file://$PROJECT_DIR$/colorSchemes/colorSchemes.iml" filepath="$PROJECT_DIR$/colorSchemes/colorSchemes.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/commander/commander.iml" filepath="$PROJECT_DIR$/plugins/commander/commander.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/common/common.iml" filepath="$PROJECT_DIR$/android/tools-base/common/common.iml" group="android/sdktools" />
|
||||
@@ -204,6 +207,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/resources/resources.iml" filepath="$PROJECT_DIR$/resources/resources.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/resources-en/resources-en.iml" filepath="$PROJECT_DIR$/resources-en/resources-en.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/python/rest/rest.iml" filepath="$PROJECT_DIR$/python/rest/rest.iml" group="python" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/rpclib/rpclib.iml" filepath="$PROJECT_DIR$/android/tools-base/rpclib/rpclib.iml" group="android/sdktools" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/script-debugger/backend/script-debugger-backend.iml" filepath="$PROJECT_DIR$/platform/script-debugger/backend/script-debugger-backend.iml" group="platform/script-debugger" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/script-debugger/debugger-ui/script-debugger-ui.iml" filepath="$PROJECT_DIR$/platform/script-debugger/debugger-ui/script-debugger-ui.iml" group="platform/script-debugger" />
|
||||
<module fileurl="file://$PROJECT_DIR$/android/tools-base/sdk-common/sdk-common.iml" filepath="$PROJECT_DIR$/android/tools-base/sdk-common/sdk-common.iml" group="android/sdktools" />
|
||||
@@ -240,6 +244,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/usageView/usageView.iml" filepath="$PROJECT_DIR$/platform/usageView/usageView.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util/util.iml" filepath="$PROJECT_DIR$/platform/util/util.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util-rt/util-rt.iml" filepath="$PROJECT_DIR$/platform/util-rt/util-rt.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/util/testSrc/util-tests.iml" filepath="$PROJECT_DIR$/platform/util/testSrc/util-tests.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/vcs-api/vcs-api.iml" filepath="$PROJECT_DIR$/platform/vcs-api/vcs-api.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/vcs-api/vcs-api-core/vcs-api-core.iml" filepath="$PROJECT_DIR$/platform/vcs-api/vcs-api-core/vcs-api-core.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/vcs-impl/vcs-impl.iml" filepath="$PROJECT_DIR$/platform/vcs-impl/vcs-impl.iml" group="platform" />
|
||||
|
||||
+2
-2
@@ -39,12 +39,12 @@ class RemoveRedundantEscapeAction implements IntentionAction {
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return "Remove Redundant Escape";
|
||||
return "Remove redundant escape";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return "Redundant Character Escape";
|
||||
return "Redundant character escape";
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
|
||||
+19
-19
@@ -13,35 +13,35 @@ INSTALLATION INSTRUCTIONS
|
||||
|
||||
./@@product@@.sh
|
||||
|
||||
to start the application.
|
||||
to start the application. As a side effect, this will initialize various
|
||||
configuration files in the ~/.@@system_selector@@ directory.
|
||||
|
||||
3. [OPTIONAL] Add the "{installation home}/bin" to your PATH environmental
|
||||
3. [OPTIONAL] Add "{installation home}/bin" to your PATH environment
|
||||
variable so that you may start @@product_full@@ from any directory.
|
||||
|
||||
4. [OPTIONAL] To adjust the value of JVM heap size open @@product@@.vmoptions
|
||||
(@@product@@64.vmoptions for 64-bit JDK), and modify the -Xms and -Xmx parameters.
|
||||
4. [OPTIONAL] To adjust the value of the JVM heap size, create
|
||||
~/.@@system_selector@@/@@product@@.vmoptions (or @@product@@64.vmoptions
|
||||
if using a 64-bit JDK), and set the -Xms and -Xms paramters. To see how
|
||||
to do this, you can reference the vmoptions file under
|
||||
"{installation home}/bin" as a model.
|
||||
|
||||
|
||||
[OPTIONAL] Changing location of "config" and "system" directory
|
||||
[OPTIONAL] Changing the location of "config" and "system" directories
|
||||
------------------------------------------------------------------------------
|
||||
By default @@product_full@@ stores all your settings under ~/.@@system_selector@@/config directory
|
||||
and stores data cache under ~/.@@system_selector@@/system directory.
|
||||
By default, @@product_full@@ stores all your settings under the ~/.@@system_selector@@/config
|
||||
directory and uses ~/.@@system_selector@@/system as a data cache.
|
||||
If you want to change these settings,
|
||||
|
||||
1. Open a console and cd into "{installation home}/bin"
|
||||
1. Open a console and cd into ~/.@@system_selector@@/
|
||||
|
||||
2. Open file "idea.properties" in an editor. You should find strings like
|
||||
2. Create the file "idea.properties" and open it in an editor. Set the
|
||||
idea.system.path and/or idea.config.path variables as desired, for
|
||||
example:
|
||||
|
||||
idea.system.path=~/.@@settings_dir@@/system
|
||||
idea.system.path=~/custom/system
|
||||
idea.config.path=~/custom/config
|
||||
|
||||
and
|
||||
|
||||
idea.config.path=~/.@@settings_dir@@/config
|
||||
|
||||
and change them.
|
||||
|
||||
3. Note that we recommend to store data cache ("system" directory) at a disk
|
||||
with at least 1G bytes free space
|
||||
3. Note that we recommend to store data cache ("system" directory) on a disk
|
||||
with at least 1GB of free space.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -820,6 +820,10 @@ def layoutAndroid(String androidHome, String androidToolsBaseHome) {
|
||||
module("lint-checks")
|
||||
module("ninepatch")
|
||||
module("perflib")
|
||||
module("rpclib")
|
||||
module("chartlib")
|
||||
module("builder-model")
|
||||
module("builder-test-api")
|
||||
}
|
||||
jar("androidAnnotations.jar") {
|
||||
fileset(dir: "$androidHome/android/annotations")
|
||||
|
||||
@@ -727,7 +727,7 @@ binding.setVariable("zipSources", { String home, String targetDir ->
|
||||
ant.delete(file: sources)
|
||||
ant.zip(destfile: sources) {
|
||||
fileset(dir: home) {
|
||||
["java", "groovy", "ipr", "iml", "form", "xml", "properties"].each {
|
||||
["java", "groovy", "ipr", "iml", "form", "xml", "properties", "kt"].each {
|
||||
include(name: "**/*.$it")
|
||||
}
|
||||
exclude(name: "**/testData/**")
|
||||
|
||||
@@ -51,6 +51,7 @@ com.android.tools.idea.wizard.TemplateWizardStateTest
|
||||
com.android.tools.idea.wizard.TemplateWizardModuleBuilderTest
|
||||
com.android.tools.idea.wizard.NewTemplateObjectWizardTest
|
||||
org.jetbrains.android.run.AndroidRunConfigurationTest
|
||||
org.jetbrains.android.run.GradleApkProviderTest
|
||||
org.jetbrains.android.facet.IdeaSourceProviderTest
|
||||
com.android.tools.idea.gradle.service.resolve.AndroidResolveTest
|
||||
com.android.tools.idea.gradle.service.resolve.AndroidDslContributorTest
|
||||
@@ -71,6 +72,23 @@ com.android.tools.idea.welcome.FirstRunWizardTest
|
||||
com.android.tools.idea.welcome.InstallComponentsTest
|
||||
com.android.tools.idea.welcome.AndroidVirtualDeviceTest
|
||||
com.android.tools.idea.wizard.ConfigureAndroidModuleStepDynamicTest
|
||||
com.android.tools.idea.editors.AndroidGeneratedSourcesFilterTest
|
||||
com.android.tools.idea.editors.theme.ThemeEditorStyleTest
|
||||
com.android.tools.idea.editors.theme.ThemeEditorUtilsTest
|
||||
com.android.tools.idea.editors.theme.qualifiers.QualifierUtilsTest
|
||||
com.android.tools.idea.gradle.IdeaAndroidProjectTest
|
||||
com.android.tools.idea.gradle.project.GradleProjectSyncDataTest
|
||||
com.android.tools.idea.npw.ConfigureAndroidModuleStepTest
|
||||
com.android.tools.idea.npw.ConfigureAndroidModuleStepDynamicTest
|
||||
com.android.tools.idea.npw.NewModuleWizardStateTest
|
||||
com.android.tools.idea.npw.NewProjectWizardTest
|
||||
com.android.tools.idea.npw.NewTemplateObjectWizardTest
|
||||
com.android.tools.idea.npw.TemplateWizardModuleBuilderTest
|
||||
com.android.tools.idea.npw.WrapArchiveWizardPathTest
|
||||
com.android.tools.idea.sdk.IdeSdksTest
|
||||
com.android.tools.idea.welcome.wizard.FirstRunWizardTest
|
||||
com.android.tools.idea.wizard.template.TemplateWizardStateTest
|
||||
com.android.tools.swing.layoutlib.GraphicsLayoutRendererTest
|
||||
|
||||
[ANDROID_BOMBED]
|
||||
com.android.tools.idea.gradle.project.GradleModuleImportTest
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -19,6 +19,7 @@ import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.ExecutionResult;
|
||||
import com.intellij.execution.configurations.RemoteConnection;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,7 @@ public interface DebugEnvironment {
|
||||
@Nullable
|
||||
ExecutionResult createExecutionResult() throws ExecutionException;
|
||||
|
||||
@NotNull
|
||||
GlobalSearchScope getSearchScope();
|
||||
|
||||
boolean isRemote();
|
||||
|
||||
@@ -46,6 +46,7 @@ public class DefaultDebugEnvironment implements DebugEnvironment {
|
||||
return state.execute(environment.getExecutor(), environment.getRunner());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GlobalSearchScope getSearchScope() {
|
||||
return mySearchScope;
|
||||
|
||||
@@ -26,10 +26,7 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
|
||||
import com.intellij.debugger.engine.requests.MethodReturnValueWatcher;
|
||||
import com.intellij.debugger.engine.requests.RequestManagerImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.impl.PrioritizedTask;
|
||||
import com.intellij.debugger.impl.*;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
@@ -1601,7 +1598,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
applyThreadFilter(getContextThread());
|
||||
final SuspendContextImpl context = getSuspendContext();
|
||||
myRunToCursorBreakpoint.setSuspendPolicy(context.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD? DebuggerSettings.SUSPEND_THREAD : DebuggerSettings.SUSPEND_ALL);
|
||||
DebugProcessImpl debugProcess = context.getDebugProcess();
|
||||
final DebugProcessImpl debugProcess = context.getDebugProcess();
|
||||
myRunToCursorBreakpoint.createRequest(debugProcess);
|
||||
DebugProcessImpl.this.myRunToCursorBreakpoint = myRunToCursorBreakpoint;
|
||||
|
||||
@@ -1609,15 +1606,17 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
super.contextAction();
|
||||
}
|
||||
else {
|
||||
myDebugProcessDispatcher.getMulticaster().resumed(getSuspendContext());
|
||||
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SourcePosition position = myRunToCursorBreakpoint.getSourcePosition();
|
||||
String name = position != null ? position.getFile().getName() : "<No File>";
|
||||
Messages.showErrorDialog(
|
||||
DebuggerBundle.message("error.running.to.cursor.no.executable.code", name, myRunToCursorBreakpoint.getLineIndex()+1),
|
||||
DebuggerBundle.message("error.running.to.cursor.no.executable.code",
|
||||
myRunToCursorBreakpoint.getSourcePosition().getFile().getName(),
|
||||
myRunToCursorBreakpoint.getLineIndex() + 1),
|
||||
UIUtil.removeMnemonic(ActionsBundle.actionText(XDebuggerActions.RUN_TO_CURSOR)));
|
||||
DebuggerSession session = debugProcess.getSession();
|
||||
session.getContextManager().setState(DebuggerContextUtil.createDebuggerContext(session, context),
|
||||
DebuggerSession.State.PAUSED, DebuggerSession.Event.CONTEXT, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
}
|
||||
|
||||
public abstract static class JavaFullValueEvaluator extends XFullValueEvaluator {
|
||||
private final EvaluationContextImpl myEvaluationContext;
|
||||
protected final EvaluationContextImpl myEvaluationContext;
|
||||
|
||||
public JavaFullValueEvaluator(@NotNull String linkText, EvaluationContextImpl evaluationContext) {
|
||||
super(linkText);
|
||||
|
||||
+3
-1
@@ -628,7 +628,9 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
final String localName = psiVar.getName();
|
||||
PsiClass variableClass = getContainingClass(psiVar);
|
||||
if (getContextPsiClass() == null || getContextPsiClass().equals(variableClass)) {
|
||||
final LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element));
|
||||
PsiElement method = PsiTreeUtil.getContextOfType(expression, PsiMethod.class, PsiLambdaExpression.class);
|
||||
boolean canScanFrames = method instanceof PsiLambdaExpression || ContextUtil.isJspImplicit(element);
|
||||
LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, canScanFrames);
|
||||
if (psiVar instanceof PsiParameter) {
|
||||
final PsiParameter param = (PsiParameter)psiVar;
|
||||
final PsiParameterList paramList = PsiTreeUtil.getParentOfType(param, PsiParameterList.class, true);
|
||||
|
||||
+56
-16
@@ -21,17 +21,27 @@
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.jdi.StackFrameProxy;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.debugger.impl.SimpleStackFrameContext;
|
||||
import com.intellij.debugger.jdi.LocalVariableProxyImpl;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,12 +51,12 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
private final String myLocalVariableName;
|
||||
private EvaluationContextImpl myContext;
|
||||
private LocalVariableProxyImpl myEvaluatedVariable;
|
||||
private final boolean myIsJspSpecial;
|
||||
private final boolean myCanScanFrames;
|
||||
private int myParameterIndex = -1;
|
||||
|
||||
public LocalVariableEvaluator(String localVariableName, boolean isJspSpecial) {
|
||||
public LocalVariableEvaluator(String localVariableName, boolean canScanFrames) {
|
||||
myLocalVariableName = localVariableName;
|
||||
myIsJspSpecial = isJspSpecial;
|
||||
myCanScanFrames = canScanFrames;
|
||||
}
|
||||
|
||||
public void setParameterIndex(int parameterIndex) {
|
||||
@@ -63,39 +73,54 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
try {
|
||||
ThreadReferenceProxyImpl threadProxy = null;
|
||||
int lastFrameIndex = -1;
|
||||
PsiVariable variable = null;
|
||||
|
||||
boolean topFrame = true;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
LocalVariableProxyImpl local = frameProxy.visibleVariableByName(myLocalVariableName);
|
||||
if (local != null) {
|
||||
myEvaluatedVariable = local;
|
||||
myContext = context;
|
||||
return frameProxy.getValue(local);
|
||||
if (topFrame ||
|
||||
variable.equals(resolveVariable(frameProxy, myLocalVariableName, context.getProject(), context.getDebugProcess()))) {
|
||||
myEvaluatedVariable = local;
|
||||
myContext = context;
|
||||
return frameProxy.getValue(local);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (EvaluateException e) {
|
||||
if (!(e.getCause() instanceof AbsentInformationException)) {
|
||||
throw e;
|
||||
}
|
||||
if (myParameterIndex < 0) {
|
||||
throw e;
|
||||
if (topFrame) {
|
||||
if (myParameterIndex < 0) {
|
||||
throw e;
|
||||
}
|
||||
final List<Value> values = frameProxy.getArgumentValues();
|
||||
if (values.isEmpty() || myParameterIndex >= values.size()) {
|
||||
throw e;
|
||||
}
|
||||
return values.get(myParameterIndex);
|
||||
}
|
||||
final List<Value> values = frameProxy.getArgumentValues();
|
||||
if (values.isEmpty() || myParameterIndex >= values.size()) {
|
||||
throw e;
|
||||
}
|
||||
return values.get(myParameterIndex);
|
||||
}
|
||||
|
||||
if (myIsJspSpecial) {
|
||||
if (myCanScanFrames) {
|
||||
if (topFrame) {
|
||||
variable = resolveVariable(frameProxy, myLocalVariableName, context.getProject(), context.getDebugProcess());
|
||||
if (variable == null) break;
|
||||
}
|
||||
if (threadProxy == null /* initialize it lazily */) {
|
||||
threadProxy = frameProxy.threadProxy();
|
||||
lastFrameIndex = threadProxy.frameCount() - 1;
|
||||
}
|
||||
final int currentFrameIndex = frameProxy.getFrameIndex();
|
||||
int currentFrameIndex = frameProxy.getFrameIndex();
|
||||
if (currentFrameIndex < lastFrameIndex) {
|
||||
frameProxy = threadProxy.frame(currentFrameIndex + 1);
|
||||
continue;
|
||||
if (frameProxy != null) {
|
||||
topFrame = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +182,21 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
return modifier;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiVariable resolveVariable(final StackFrameProxy frame,
|
||||
final String name,
|
||||
final Project project,
|
||||
final DebugProcess process) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<PsiVariable>() {
|
||||
@Override
|
||||
public PsiVariable compute() {
|
||||
PsiElement place = PositionUtil.getContextElement(new SimpleStackFrameContext(frame, process));
|
||||
if (place == null) return null;
|
||||
return JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(name, place);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myLocalVariableName;
|
||||
|
||||
@@ -241,15 +241,8 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
|
||||
debugProcess.removeDebugProcessListener(this);
|
||||
}
|
||||
});
|
||||
DebuggerSession session = new DebuggerSession(environment.getSessionName(), debugProcess);
|
||||
ExecutionResult executionResult;
|
||||
try {
|
||||
executionResult = session.attach(environment);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
session.dispose();
|
||||
throw e;
|
||||
}
|
||||
DebuggerSession session = DebuggerSession.create(environment.getSessionName(), debugProcess, environment);
|
||||
ExecutionResult executionResult = session.getProcess().getExecutionResult();
|
||||
if (executionResult == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager;
|
||||
import com.sun.jdi.ObjectCollectedException;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.event.Event;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
import com.sun.jdi.request.StepRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -96,7 +95,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
|
||||
private final String mySessionName;
|
||||
private final DebugProcessImpl myDebugProcess;
|
||||
private @NotNull GlobalSearchScope mySearchScope;
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
|
||||
private final DebuggerContextImpl SESSION_EMPTY_CONTEXT;
|
||||
//Thread, user is currently stepping through
|
||||
@@ -118,8 +117,6 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
|
||||
@NotNull
|
||||
public GlobalSearchScope getSearchScope() {
|
||||
//noinspection ConstantConditions
|
||||
LOG.assertTrue(mySearchScope != null, "Accessing Session's search scope before its initialization");
|
||||
return mySearchScope;
|
||||
}
|
||||
|
||||
@@ -187,7 +184,20 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
}
|
||||
}
|
||||
|
||||
protected DebuggerSession(String sessionName, final DebugProcessImpl debugProcess) {
|
||||
static DebuggerSession create(String sessionName, @NotNull final DebugProcessImpl debugProcess, DebugEnvironment environment)
|
||||
throws ExecutionException {
|
||||
DebuggerSession session = new DebuggerSession(sessionName, debugProcess, environment);
|
||||
try {
|
||||
session.attach(environment);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
session.dispose();
|
||||
throw e;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
private DebuggerSession(String sessionName, @NotNull final DebugProcessImpl debugProcess, DebugEnvironment environment) {
|
||||
mySessionName = sessionName;
|
||||
myDebugProcess = debugProcess;
|
||||
SESSION_EMPTY_CONTEXT = DebuggerContextImpl.createDebuggerContext(this, null, null, null);
|
||||
@@ -196,6 +206,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
myDebugProcess.addDebugProcessListener(new MyDebugProcessListener(debugProcess));
|
||||
myDebugProcess.addEvaluationListener(new MyEvaluationListener());
|
||||
ValueLookupManager.getInstance(getProject()).startListening();
|
||||
mySearchScope = environment.getSearchScope();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -211,6 +222,7 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
return mySessionName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DebugProcessImpl getProcess() {
|
||||
return myDebugProcess;
|
||||
}
|
||||
@@ -400,11 +412,10 @@ public class DebuggerSession implements AbstractDebuggerSession {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ExecutionResult attach(DebugEnvironment environment) throws ExecutionException {
|
||||
private ExecutionResult attach(DebugEnvironment environment) throws ExecutionException {
|
||||
RemoteConnection remoteConnection = environment.getRemoteConnection();
|
||||
final String addressDisplayName = DebuggerBundle.getAddressDisplayName(remoteConnection);
|
||||
final String transportName = DebuggerBundle.getTransportName(remoteConnection);
|
||||
mySearchScope = environment.getSearchScope();
|
||||
final ExecutionResult executionResult = myDebugProcess.attachVirtualMachine(environment, this);
|
||||
getContextManager().setState(SESSION_EMPTY_CONTEXT, State.WAITING_ATTACH,
|
||||
Event.START_WAIT_ATTACH,
|
||||
|
||||
@@ -121,6 +121,10 @@ class ReloadClassesWorker {
|
||||
|
||||
int processedEntriesCount = 0;
|
||||
for (final Map.Entry<String, HotSwapFile> entry : modifiedClasses.entrySet()) {
|
||||
// stop if process is finished already
|
||||
if (debugProcess.isDetached() || debugProcess.isDetaching()) {
|
||||
break;
|
||||
}
|
||||
if (redefineProcessor.getProcessedClassesCount() == 0 && myProgress.isCancelled()) {
|
||||
// once at least one class has been actually reloaded, do not interrupt the whole process
|
||||
break;
|
||||
|
||||
+40
-4
@@ -32,8 +32,11 @@ import com.intellij.xdebugger.breakpoints.XBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -50,6 +53,10 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
super("java-line", DebuggerBundle.message("line.breakpoints.tab.title"));
|
||||
}
|
||||
|
||||
protected JavaLineBreakpointType(@NonNls @NotNull String id, @Nls @NotNull String title) {
|
||||
super(id, title);
|
||||
}
|
||||
|
||||
//@Override
|
||||
protected String getHelpID() {
|
||||
return HelpID.LINE_BREAKPOINTS;
|
||||
@@ -129,10 +136,39 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
return res;
|
||||
}
|
||||
|
||||
class JavaBreakpointVariant extends XLineBreakpointVariant {
|
||||
public boolean matchesPosition(@NotNull LineBreakpoint<?> breakpoint, @NotNull SourcePosition position) {
|
||||
JavaBreakpointProperties properties = breakpoint.getProperties();
|
||||
if (properties == null || properties instanceof JavaLineBreakpointProperties) {
|
||||
if (properties != null && ((JavaLineBreakpointProperties)properties).getLambdaOrdinal() == null) return true;
|
||||
PsiElement containingMethod = getContainingMethod(breakpoint);
|
||||
if (containingMethod == null) return false;
|
||||
return DebuggerUtilsEx.inTheMethod(position, containingMethod);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getContainingMethod(@NotNull LineBreakpoint<?> breakpoint) {
|
||||
SourcePosition position = breakpoint.getSourcePosition();
|
||||
if (position == null) return null;
|
||||
|
||||
JavaBreakpointProperties properties = breakpoint.getProperties();
|
||||
if (properties instanceof JavaLineBreakpointProperties) {
|
||||
Integer ordinal = ((JavaLineBreakpointProperties)properties).getLambdaOrdinal();
|
||||
if (ordinal > -1) {
|
||||
List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(position, true);
|
||||
if (ordinal < lambdas.size()) {
|
||||
return lambdas.get(ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return DebuggerUtilsEx.getContainingMethod(position);
|
||||
}
|
||||
|
||||
public class JavaBreakpointVariant extends XLineBreakpointVariant {
|
||||
protected final XSourcePosition mySourcePosition;
|
||||
|
||||
private JavaBreakpointVariant(XSourcePosition position) {
|
||||
public JavaBreakpointVariant(XSourcePosition position) {
|
||||
mySourcePosition = position;
|
||||
}
|
||||
|
||||
@@ -158,7 +194,7 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
}
|
||||
}
|
||||
|
||||
private class ExactJavaBreakpointVariant extends JavaBreakpointVariant {
|
||||
public class ExactJavaBreakpointVariant extends JavaBreakpointVariant {
|
||||
private final PsiElement myElement;
|
||||
private final Integer myLambdaOrdinal;
|
||||
|
||||
@@ -200,7 +236,7 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
if (ordinal != null) {
|
||||
Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
|
||||
if (javaBreakpoint instanceof LineBreakpoint) {
|
||||
PsiElement method = ((LineBreakpoint)javaBreakpoint).getContainingMethod();
|
||||
PsiElement method = getContainingMethod((LineBreakpoint)javaBreakpoint);
|
||||
if (method != null) {
|
||||
return method.getTextRange();
|
||||
}
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public abstract class JavaLineBreakpointTypeBase<P extends JavaBreakpointPropert
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
|
||||
public boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
// JSPX supports jvm debugging, but not in XHTML files
|
||||
if (psiFile == null || psiFile.getViewProvider().getFileType() == StdFileTypes.XHTML) {
|
||||
|
||||
@@ -63,7 +63,6 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -210,34 +209,18 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
if (getProperties() instanceof JavaLineBreakpointProperties) {
|
||||
Integer ordinal = ((JavaLineBreakpointProperties)getProperties()).getLambdaOrdinal();
|
||||
if (ordinal == null) return true;
|
||||
PsiElement containingMethod = getContainingMethod();
|
||||
if (containingMethod == null) return false;
|
||||
SourcePosition position = debugProcess.getPositionManager().getSourcePosition(loc);
|
||||
if (position == null) return false;
|
||||
return DebuggerUtilsEx.inTheMethod(position, containingMethod);
|
||||
}
|
||||
return true;
|
||||
SourcePosition position = debugProcess.getPositionManager().getSourcePosition(loc);
|
||||
if (position == null) return false;
|
||||
JavaLineBreakpointType type = getXBreakpointType();
|
||||
if (type == null) return true;
|
||||
return type.matchesPosition(LineBreakpoint.this, position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getContainingMethod() {
|
||||
SourcePosition position = getSourcePosition();
|
||||
if (position == null) return null;
|
||||
if (getProperties() instanceof JavaLineBreakpointProperties) {
|
||||
Integer ordinal = ((JavaLineBreakpointProperties)getProperties()).getLambdaOrdinal();
|
||||
if (ordinal > -1) {
|
||||
List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(position, true);
|
||||
if (ordinal < lambdas.size()) {
|
||||
return lambdas.get(ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return DebuggerUtilsEx.getContainingMethod(position);
|
||||
protected JavaLineBreakpointType getXBreakpointType() {
|
||||
return (JavaLineBreakpointType)myXBreakpoint.getType();
|
||||
}
|
||||
|
||||
private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) {
|
||||
|
||||
+14
-14
@@ -17,15 +17,13 @@ package com.intellij.debugger.ui.breakpoints;
|
||||
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.xdebugger.XDebuggerUtil;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.sun.jdi.Location;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpointType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
|
||||
@@ -47,6 +45,7 @@ public class RunToCursorBreakpoint<P extends JavaBreakpointProperties> extends L
|
||||
myRestoreBreakpoints = restoreBreakpoints;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SourcePosition getSourcePosition() {
|
||||
return myCustomPosition;
|
||||
@@ -125,17 +124,18 @@ public class RunToCursorBreakpoint<P extends JavaBreakpointProperties> extends L
|
||||
return false; // always enabled
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected boolean acceptLocation(final DebugProcessImpl debugProcess, ReferenceType classType, final Location loc) {
|
||||
if (!super.acceptLocation(debugProcess, classType, loc)) return false;
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
SourcePosition position = debugProcess.getPositionManager().getSourcePosition(loc);
|
||||
if (position == null) return false;
|
||||
return DebuggerUtilsEx.inTheSameMethod(myCustomPosition, position);
|
||||
protected JavaLineBreakpointType getXBreakpointType() {
|
||||
SourcePosition position = getSourcePosition();
|
||||
VirtualFile file = position.getFile().getVirtualFile();
|
||||
int line = position.getLine();
|
||||
for (XLineBreakpointType<?> type : XDebuggerUtil.getInstance().getLineBreakpointTypes()) {
|
||||
if (type instanceof JavaLineBreakpointType && type.canPutAt(file, line, getProject())) {
|
||||
return ((JavaLineBreakpointType)type);
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -69,7 +69,7 @@ public class MethodListDlg extends DialogWrapper {
|
||||
}
|
||||
}.installOn(myList);
|
||||
|
||||
ListScrollingUtil.ensureSelectionExists(myList);
|
||||
ScrollingUtil.ensureSelectionExists(myList);
|
||||
setTitle(ExecutionBundle.message("choose.test.method.dialog.title"));
|
||||
init();
|
||||
}
|
||||
|
||||
+6
-4
@@ -552,11 +552,13 @@ public class TestDiscoveryIndex implements ProjectComponent {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int classQName : previousClassData.keys()) {
|
||||
if (classData.containsKey(classQName)) continue;
|
||||
if (classData != null) {
|
||||
for (int classQName : previousClassData.keys()) {
|
||||
if (classData.containsKey(classQName)) continue;
|
||||
|
||||
TIntArrayList previousMethods = previousClassData.get(classQName);
|
||||
removedClassData.put(classQName, previousMethods);
|
||||
TIntArrayList previousMethods = previousClassData.get(classQName);
|
||||
removedClassData.put(classQName, previousMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -22,7 +22,6 @@ import com.intellij.execution.configurations.ConfigurationType;
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration;
|
||||
import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
|
||||
import com.intellij.execution.junit2.info.MethodLocation;
|
||||
import com.intellij.execution.testframework.TestsUIUtil;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
@@ -31,6 +30,7 @@ import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -153,13 +153,13 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
|
||||
|
||||
public static String getQName(PsiElement psiMember, Location location) {
|
||||
if (psiMember instanceof PsiClass) {
|
||||
return ((PsiClass)psiMember).getQualifiedName();
|
||||
return ClassUtil.getJVMClassName((PsiClass)psiMember);
|
||||
}
|
||||
else if (psiMember instanceof PsiMember) {
|
||||
final PsiClass containingClass = location instanceof MethodLocation
|
||||
? ((MethodLocation)location).getContainingClass(): ((PsiMember)psiMember).getContainingClass();
|
||||
assert containingClass != null;
|
||||
return containingClass.getQualifiedName() + "," + ((PsiMember)psiMember).getName();
|
||||
return ClassUtil.getJVMClassName(containingClass) + "," + ((PsiMember)psiMember).getName();
|
||||
} else if (psiMember instanceof PsiPackage) {
|
||||
return ((PsiPackage)psiMember).getQualifiedName();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -33,6 +33,7 @@ import com.intellij.openapi.wm.ex.WindowManagerEx;
|
||||
import com.intellij.ui.ClickListener;
|
||||
import com.intellij.ui.DoubleClickListener;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.ScrollingUtil;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
@@ -47,8 +48,6 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.ui.ListScrollingUtil.ensureSelectionExists;
|
||||
|
||||
public class JdkChooserPanel extends JPanel {
|
||||
private JList myList = null;
|
||||
private DefaultListModel myListModel = null;
|
||||
@@ -226,7 +225,7 @@ public class JdkChooserPanel extends JPanel {
|
||||
jdkChooserPanel.selectJdk(jdkToSelect);
|
||||
}
|
||||
else {
|
||||
ensureSelectionExists(jdkChooserPanel.myList);
|
||||
ScrollingUtil.ensureSelectionExists(jdkChooserPanel.myList);
|
||||
}
|
||||
new DoubleClickListener() {
|
||||
@Override
|
||||
|
||||
+38
@@ -359,6 +359,10 @@ public class HighlightMethodUtil {
|
||||
} else {
|
||||
highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange);
|
||||
}
|
||||
|
||||
if (highlightInfo == null) {
|
||||
highlightInfo = checkVarargParameterErasureToBeAccessible((MethodCandidateInfo)resolveResult, methodCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1509,9 +1513,43 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != null && !holder.hasErrorResults()) {
|
||||
holder.add(checkVarargParameterErasureToBeAccessible(result, constructorCall));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the compile-time declaration is applicable by variable arity invocation,
|
||||
* then where the last formal parameter type of the invocation type of the method is Fn[],
|
||||
* it is a compile-time error if the type which is the erasure of Fn is not accessible at the point of invocation.
|
||||
*/
|
||||
private static HighlightInfo checkVarargParameterErasureToBeAccessible(MethodCandidateInfo info, PsiCall place) {
|
||||
final PsiMethod method = info.getElement();
|
||||
if (info.isVarargs() || method.isVarArgs() && !PsiUtil.isLanguageLevel8OrHigher(place)) {
|
||||
if (method.hasTypeParameters()) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiType componentType = ((PsiEllipsisType)parameters[parameters.length - 1].getType()).getComponentType();
|
||||
final PsiClass classOfComponent = PsiUtil.resolveClassInClassTypeOnly(componentType);
|
||||
if (classOfComponent instanceof PsiTypeParameter) {
|
||||
final PsiType substitutedTypeErasure = TypeConversionUtil.erasure(info.getSubstitutor().substitute(componentType));
|
||||
final PsiClass targetClass = PsiUtil.resolveClassInClassTypeOnly(substitutedTypeErasure);
|
||||
if (targetClass != null && !PsiUtil.isAccessible(targetClass, place, null)) {
|
||||
final PsiExpressionList argumentList = place.getArgumentList();
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.descriptionAndTooltip("Formal varargs element type " +
|
||||
PsiFormatUtil.formatClass(targetClass, PsiFormatUtilBase.SHOW_FQ_NAME) +
|
||||
" is inaccessible here")
|
||||
.range(argumentList != null ? argumentList : place)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void registerFixesOnInvalidConstructorCall(PsiConstructorCall constructorCall,
|
||||
PsiJavaCodeReferenceElement classReference,
|
||||
PsiExpressionList list,
|
||||
|
||||
+23
-11
@@ -351,11 +351,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (result != null) {
|
||||
myHolder.add(result);
|
||||
} else {
|
||||
final PsiClass samClass = resolveResult.getElement();
|
||||
if (!PsiUtil.isAccessible(myFile.getProject(), samClass, expression, null)) {
|
||||
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
|
||||
.descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
|
||||
}
|
||||
checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1291,12 +1287,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
if (!myHolder.hasErrorResults()) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass != null && !PsiUtil.isAccessible(myFile.getProject(), psiClass, expression, null)) {
|
||||
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
|
||||
.descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
|
||||
}
|
||||
final PsiClassType.ClassResolveResult resolveResult = checkFunctionalInterfaceTypeAccessible(expression, functionalInterfaceType);
|
||||
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
|
||||
if (interfaceMethod != null) {
|
||||
@@ -1381,6 +1372,27 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
}
|
||||
}
|
||||
|
||||
// 15.13 | 15.27
|
||||
// It is a compile-time error if any class or interface mentioned by either U or the function type of U
|
||||
// is not accessible from the class or interface in which the method reference expression appears.
|
||||
private PsiClassType.ClassResolveResult checkFunctionalInterfaceTypeAccessible(PsiFunctionalExpression expression,
|
||||
PsiType functionalInterfaceType) {
|
||||
PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass != null) {
|
||||
if (!PsiUtil.isAccessible(myFile.getProject(), psiClass, expression, null)) {
|
||||
myHolder.add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression)
|
||||
.descriptionAndTooltip(HighlightUtil.buildProblemWithAccessDescription(expression, resolveResult)).create());
|
||||
}
|
||||
else {
|
||||
for (PsiType type : resolveResult.getSubstitutor().getSubstitutionMap().values()) {
|
||||
checkFunctionalInterfaceTypeAccessible(expression, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resolveResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceList(PsiReferenceList list) {
|
||||
if (list.getFirstChild() == null) return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -209,13 +209,17 @@ public class JavaSuppressionUtil {
|
||||
return statement;
|
||||
}
|
||||
|
||||
PsiVariable local = PsiTreeUtil.getParentOfType(place, PsiVariable.class, false);
|
||||
if (local != null && getAnnotationMemberSuppressedIn(local, toolId) != null) {
|
||||
PsiModifierList modifierList = local.getModifierList();
|
||||
return modifierList != null ? modifierList.findAnnotation(SUPPRESS_INSPECTIONS_ANNOTATION_NAME) : null;
|
||||
PsiModifierListOwner up = PsiTreeUtil.getNonStrictParentOfType(place, PsiVariable.class, PsiDocCommentOwner.class);
|
||||
if (up instanceof PsiVariable) {
|
||||
PsiVariable local = (PsiVariable)up;
|
||||
if (getAnnotationMemberSuppressedIn(local, toolId) != null) {
|
||||
PsiModifierList modifierList = local.getModifierList();
|
||||
return modifierList != null ? modifierList.findAnnotation(SUPPRESS_INSPECTIONS_ANNOTATION_NAME) : null;
|
||||
}
|
||||
}
|
||||
|
||||
PsiDocCommentOwner container = PsiTreeUtil.getNonStrictParentOfType(place, PsiDocCommentOwner.class);
|
||||
PsiDocCommentOwner container = up == null || up instanceof PsiDocCommentOwner
|
||||
? (PsiDocCommentOwner)up : PsiTreeUtil.getNonStrictParentOfType(up, PsiDocCommentOwner.class);
|
||||
while (true) {
|
||||
if (!(container instanceof PsiTypeParameter)) break;
|
||||
container = PsiTreeUtil.getParentOfType(container, PsiDocCommentOwner.class);
|
||||
|
||||
+13
-2
@@ -37,7 +37,7 @@ import java.util.Collections;
|
||||
public class RefJavaUtilImpl extends RefJavaUtil{
|
||||
|
||||
@Override
|
||||
public void addReferences(@NotNull final PsiModifierListOwner psiFrom, @NotNull final RefJavaElement ref, @Nullable PsiElement findIn) {
|
||||
public void addReferences(@NotNull final PsiModifierListOwner psiFrom, @NotNull final RefJavaElement ref, @Nullable final PsiElement findIn) {
|
||||
final RefJavaElementImpl refFrom = (RefJavaElementImpl)ref;
|
||||
if (findIn == null) {
|
||||
return;
|
||||
@@ -61,7 +61,8 @@ public class RefJavaUtilImpl extends RefJavaUtil{
|
||||
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
visitElement(expression);
|
||||
|
||||
PsiElement psiResolved = expression.resolve();
|
||||
final JavaResolveResult result = expression.advancedResolve(false);
|
||||
final PsiElement psiResolved = result.getElement();
|
||||
|
||||
if (psiResolved instanceof PsiModifierListOwner) {
|
||||
if (isDeprecated(psiResolved)) refFrom.setUsesDeprecatedApi(true);
|
||||
@@ -76,6 +77,16 @@ public class RefJavaUtilImpl extends RefJavaUtil{
|
||||
if (refResolved instanceof RefMethod) {
|
||||
updateRefMethod(psiResolved, refResolved, expression, psiFrom, refFrom);
|
||||
}
|
||||
|
||||
if (psiResolved instanceof PsiMember && result.getCurrentFileResolveScope() instanceof PsiImportStaticStatement) {
|
||||
final PsiClass containingClass = ((PsiMember)psiResolved).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
RefElement refContainingClass = refFrom.getRefManager().getReference(containingClass);
|
||||
if (refContainingClass != null) {
|
||||
refFrom.addReference(refContainingClass, containingClass, psiFrom, false, true, expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -300,6 +300,10 @@ public class InputVariables {
|
||||
}
|
||||
}
|
||||
|
||||
public ParametersFolder getFolding() {
|
||||
return myFolding;
|
||||
}
|
||||
|
||||
public void setFoldingAvailable(boolean foldingAvailable) {
|
||||
myFoldingAvailable = foldingAvailable;
|
||||
|
||||
|
||||
+2
-2
@@ -31,7 +31,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.AnActionButton;
|
||||
import com.intellij.ui.AnActionButtonRunnable;
|
||||
import com.intellij.ui.ListScrollingUtil;
|
||||
import com.intellij.ui.ScrollingUtil;
|
||||
import com.intellij.ui.ToolbarDecorator;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -96,7 +96,7 @@ public class JavaAutoImportOptions implements AutoImportOptionsProvider {
|
||||
|
||||
myExcludePackagesModel.add(index, packageName);
|
||||
myExcludePackagesList.setSelectedValue(packageName, true);
|
||||
ListScrollingUtil.ensureIndexIsVisible(myExcludePackagesList, index, 0);
|
||||
ScrollingUtil.ensureIndexIsVisible(myExcludePackagesList, index, 0);
|
||||
IdeFocusManager.getGlobalInstance().requestFocus(myExcludePackagesList, false);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -57,13 +57,13 @@ public class BasicExpressionCompletionContributor {
|
||||
final Consumer<LookupElement> result,
|
||||
PrefixMatcher matcher) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
if (JavaCompletionData.isAfterTypeDot(element)) {
|
||||
if (JavaKeywordCompletion.isAfterTypeDot(element)) {
|
||||
addKeyword(result, element, PsiKeyword.CLASS);
|
||||
addKeyword(result, element, PsiKeyword.THIS);
|
||||
|
||||
}
|
||||
|
||||
if (!JavaCompletionData.AFTER_DOT.accepts(element)) {
|
||||
if (!JavaKeywordCompletion.AFTER_DOT.accepts(element)) {
|
||||
if (parameters.getParameters().getInvocationCount() <= 1) {
|
||||
new CollectionsUtilityMethodsProvider(parameters.getPosition(),
|
||||
parameters.getExpectedType(),
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,12 +30,10 @@ import java.util.Set;
|
||||
* @author peter
|
||||
*/
|
||||
public class InheritorsHolder implements Consumer<LookupElement> {
|
||||
private final PsiElement myPosition;
|
||||
private final Set<String> myAddedClasses = new HashSet<String>();
|
||||
private final CompletionResultSet myResult;
|
||||
|
||||
public InheritorsHolder(PsiElement position, CompletionResultSet result) {
|
||||
myPosition = position;
|
||||
public InheritorsHolder(CompletionResultSet result) {
|
||||
myResult = result;
|
||||
}
|
||||
|
||||
@@ -49,12 +46,12 @@ public class InheritorsHolder implements Consumer<LookupElement> {
|
||||
myResult.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement));
|
||||
}
|
||||
|
||||
public void registerClass(PsiClass psiClass) {
|
||||
public void registerClass(@NotNull PsiClass psiClass) {
|
||||
ContainerUtil.addIfNotNull(myAddedClasses, getClassName(psiClass));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getClassName(PsiClass psiClass) {
|
||||
private static String getClassName(@NotNull PsiClass psiClass) {
|
||||
String name = psiClass.getQualifiedName();
|
||||
return name == null ? psiClass.getName() : name;
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.*;
|
||||
import com.intellij.psi.filters.position.LeftNeighbour;
|
||||
import com.intellij.psi.filters.position.SuperParentFilter;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class Java15CompletionData extends JavaCompletionData {
|
||||
|
||||
@Override
|
||||
protected void initVariantsInFileScope() {
|
||||
super.initVariantsInFileScope();
|
||||
//static keyword in static import
|
||||
{
|
||||
final CompletionVariant variant = new CompletionVariant(PsiImportList.class, new LeftNeighbour(new TextFilter (PsiKeyword.IMPORT)));
|
||||
variant.addCompletion(PsiKeyword.STATIC, TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
{
|
||||
final ElementFilter position = new AndFilter(new LeftNeighbour(new TextFilter("@")),
|
||||
new NotFilter(new SuperParentFilter(
|
||||
new OrFilter(new ClassFilter(PsiNameValuePair.class),
|
||||
new ClassFilter(PsiParameterList.class))))
|
||||
);
|
||||
|
||||
final CompletionVariant variant = new CompletionVariant(PsiJavaFile.class, position);
|
||||
variant.includeScopeClass(PsiClass.class);
|
||||
|
||||
variant.addCompletion(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
|
||||
public class Java18CompletionData extends Java15CompletionData {
|
||||
private static final PsiElementPattern<PsiElement, ?> AFTER_DOUBLE_COLON = psiElement()
|
||||
.afterLeaf(psiElement(JavaTokenType.DOUBLE_COLON));
|
||||
|
||||
@Override
|
||||
public void fillCompletions(final CompletionParameters parameters, final Consumer<LookupElement> result) {
|
||||
PsiElement position = parameters.getPosition();
|
||||
|
||||
if (!inComment(position)) {
|
||||
if (AFTER_DOUBLE_COLON.accepts(position)) {
|
||||
PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiMethodReferenceExpression.class);
|
||||
TailType tail = parent != null && !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE;
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), tail));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSuitableForClass(position)) {
|
||||
PsiElement scope = position.getParent();
|
||||
while (scope != null && !(scope instanceof PsiFile)) {
|
||||
if (scope instanceof PsiClass && ((PsiClass)scope).isInterface()) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
break;
|
||||
}
|
||||
scope = scope.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.fillCompletions(parameters, result);
|
||||
}
|
||||
|
||||
private static boolean inComment(final PsiElement position) {
|
||||
return PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.LookupItemUtil;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaAwareCompletionData extends CompletionData{
|
||||
|
||||
@Override
|
||||
protected void addLookupItem(Set<LookupElement> set, final TailType tailType, @NotNull Object completion, final PsiFile file, final CompletionVariant variant) {
|
||||
if (completion instanceof LookupElement && !(completion instanceof LookupItem)) {
|
||||
set.add((LookupElement)completion);
|
||||
return;
|
||||
}
|
||||
|
||||
LookupElement _ret = LookupItemUtil.objectToLookupItem(completion);
|
||||
if(_ret == null || !(_ret instanceof LookupItem)) return;
|
||||
|
||||
LookupItem ret = (LookupItem)_ret;
|
||||
ret.setInsertHandler(new InsertHandler<LookupElement>() {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context, LookupElement item) {
|
||||
if (context.shouldAddCompletionChar()) {
|
||||
return;
|
||||
}
|
||||
if (tailType != TailType.NONE && tailType.isApplicable(context)) {
|
||||
tailType.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Map<Object, Object> itemProperties = variant.getItemProperties();
|
||||
for (final Object key : itemProperties.keySet()) {
|
||||
ret.setAttribute(key, itemProperties.get(key));
|
||||
}
|
||||
|
||||
set.add(ret);
|
||||
}
|
||||
|
||||
protected void addKeyword(Set<LookupElement> set,
|
||||
final TailType tailType,
|
||||
final Object comp,
|
||||
final PrefixMatcher matcher,
|
||||
final PsiFile file,
|
||||
final CompletionVariant variant) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory();
|
||||
for (final LookupElement item : set) {
|
||||
if (item.getObject().toString().equals(comp.toString())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
try{
|
||||
final PsiKeyword keyword = factory.createKeyword((String)comp);
|
||||
addLookupItem(set, tailType, keyword, file, variant);
|
||||
}
|
||||
catch(IncorrectOperationException e){
|
||||
addLookupItem(set, tailType, comp, file, variant);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+73
-53
@@ -38,7 +38,6 @@ import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PatternCondition;
|
||||
import com.intellij.patterns.PsiJavaElementPattern;
|
||||
import com.intellij.patterns.PsiNameValuePairPattern;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.filters.*;
|
||||
@@ -54,13 +53,19 @@ import com.intellij.psi.scope.ElementClassFilter;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
import static com.intellij.util.ObjectUtils.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -68,28 +73,11 @@ import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
public class JavaCompletionContributor extends CompletionContributor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.JavaCompletionContributor");
|
||||
|
||||
private static final Map<LanguageLevel, JavaCompletionData> ourCompletionData;
|
||||
|
||||
static {
|
||||
ourCompletionData = new LinkedHashMap<LanguageLevel, JavaCompletionData>();
|
||||
ourCompletionData.put(LanguageLevel.JDK_1_8, new Java18CompletionData());
|
||||
ourCompletionData.put(LanguageLevel.JDK_1_5, new Java15CompletionData());
|
||||
ourCompletionData.put(LanguageLevel.JDK_1_3, new JavaCompletionData());
|
||||
}
|
||||
|
||||
public static final ElementPattern<PsiElement> ANNOTATION_NAME = psiElement().
|
||||
withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).afterLeaf("@");
|
||||
private static final PsiJavaElementPattern.Capture<PsiElement> UNEXPECTED_REFERENCE_AFTER_DOT =
|
||||
psiElement().afterLeaf(".").insideStarting(psiExpressionStatement());
|
||||
|
||||
private static JavaCompletionData getCompletionData(LanguageLevel level) {
|
||||
final Set<Map.Entry<LanguageLevel, JavaCompletionData>> entries = ourCompletionData.entrySet();
|
||||
for (Map.Entry<LanguageLevel, JavaCompletionData> entry : entries) {
|
||||
if (entry.getKey().isAtLeast(level)) return entry.getValue();
|
||||
}
|
||||
return ourCompletionData.get(LanguageLevel.JDK_1_3);
|
||||
}
|
||||
|
||||
private static final PsiNameValuePairPattern NAME_VALUE_PAIR =
|
||||
psiNameValuePair().withSuperParent(2, psiElement(PsiAnnotation.class));
|
||||
private static final ElementPattern<PsiElement> ANNOTATION_ATTRIBUTE_NAME =
|
||||
@@ -124,8 +112,8 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return new AnnotationTypeFilter();
|
||||
}
|
||||
|
||||
if (JavaCompletionData.DECLARATION_START.getValue().accepts(position) ||
|
||||
JavaCompletionData.isInsideParameterList(position) ||
|
||||
if (JavaKeywordCompletion.DECLARATION_START.getValue().accepts(position) ||
|
||||
JavaKeywordCompletion.isInsideParameterList(position) ||
|
||||
psiElement().inside(psiElement(PsiJavaCodeReferenceElement.class).withParent(psiAnnotation())).accepts(position)) {
|
||||
return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER);
|
||||
}
|
||||
@@ -134,18 +122,18 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return new ElementExtractorFilter(ElementClassFilter.CLASS);
|
||||
}
|
||||
|
||||
if (JavaCompletionData.VARIABLE_AFTER_FINAL.accepts(position)) {
|
||||
if (JavaKeywordCompletion.VARIABLE_AFTER_FINAL.accepts(position)) {
|
||||
return ElementClassFilter.CLASS;
|
||||
}
|
||||
|
||||
if (JavaCompletionData.AFTER_TRY_BLOCK.isAcceptable(position, position) ||
|
||||
JavaCompletionData.START_SWITCH.accepts(position) ||
|
||||
JavaCompletionData.isInstanceofPlace(position) ||
|
||||
JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
|
||||
if (psiElement().afterLeaf(psiElement(JavaTokenType.RBRACE).withParents(PsiCodeBlock.class, PsiTryStatement.class)).accepts(position) ||
|
||||
JavaKeywordCompletion.START_SWITCH.accepts(position) ||
|
||||
JavaKeywordCompletion.isInstanceofPlace(position) ||
|
||||
JavaKeywordCompletion.isAfterPrimitiveOrArrayType(position)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (JavaCompletionData.START_FOR.accepts(position)) {
|
||||
if (JavaKeywordCompletion.START_FOR.accepts(position)) {
|
||||
return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.VARIABLE);
|
||||
}
|
||||
|
||||
@@ -212,14 +200,14 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
|
||||
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
|
||||
|
||||
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position) && !JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
|
||||
JavaCompletionData.addExpectedTypeMembers(parameters, result);
|
||||
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position) && !JavaKeywordCompletion.isAfterPrimitiveOrArrayType(position)) {
|
||||
JavaKeywordCompletion.addExpectedTypeMembers(parameters, result);
|
||||
completeAnnotationAttributeName(result, position, parameters);
|
||||
result.stopHere();
|
||||
return;
|
||||
}
|
||||
|
||||
final InheritorsHolder inheritors = new InheritorsHolder(position, result);
|
||||
final InheritorsHolder inheritors = new InheritorsHolder(result);
|
||||
if (JavaSmartCompletionContributor.IN_TYPE_ARGS.accepts(position)) {
|
||||
new TypeArgumentCompletionProvider(false, inheritors).addCompletions(parameters, new ProcessingContext(), result);
|
||||
}
|
||||
@@ -233,6 +221,26 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE).generateVariants(parameters, matcher, inheritors);
|
||||
}
|
||||
|
||||
if (MethodReturnTypeProvider.IN_METHOD_RETURN_TYPE.accepts(position)) {
|
||||
MethodReturnTypeProvider.addProbableReturnTypes(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
registerClassFromTypeElement(element, inheritors);
|
||||
result.addElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (SmartCastProvider.shouldSuggestCast(parameters)) {
|
||||
SmartCastProvider.addCastVariants(parameters, new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
registerClassFromTypeElement(element, inheritors);
|
||||
result.addElement(PrioritizedLookupElement.withPriority(element, 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PsiElement parent = position.getParent();
|
||||
if (parent instanceof PsiReferenceExpression) {
|
||||
final List<ExpectedTypeInfo> expected = Arrays.asList(ExpectedTypesProvider.getExpectedTypes((PsiExpression)parent, true));
|
||||
@@ -270,10 +278,19 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
result.stopHere();
|
||||
}
|
||||
|
||||
private void addExpressionVariants(@NotNull CompletionParameters parameters, PsiElement position, CompletionResultSet result) {
|
||||
private static void registerClassFromTypeElement(LookupElement element, InheritorsHolder inheritors) {
|
||||
PsiType type = assertNotNull(element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY)).getPsiType();
|
||||
PsiClass aClass =
|
||||
type instanceof PsiClassType && ((PsiClassType)type).getParameterCount() == 0 ? ((PsiClassType)type).resolve() : null;
|
||||
if (aClass != null) {
|
||||
inheritors.registerClass(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExpressionVariants(@NotNull CompletionParameters parameters, PsiElement position, CompletionResultSet result) {
|
||||
if (JavaSmartCompletionContributor.INSIDE_EXPRESSION.accepts(position) &&
|
||||
!JavaCompletionData.AFTER_DOT.accepts(position)) {
|
||||
JavaCompletionData.addExpectedTypeMembers(parameters, result);
|
||||
!JavaKeywordCompletion.AFTER_DOT.accepts(position) && !SmartCastProvider.shouldSuggestCast(parameters)) {
|
||||
JavaKeywordCompletion.addExpectedTypeMembers(parameters, result);
|
||||
if (SameSignatureCallParametersProvider.IN_CALL_ARGUMENT.accepts(position)) {
|
||||
new SameSignatureCallParametersProvider().addCompletions(parameters, new ProcessingContext(), result);
|
||||
}
|
||||
@@ -318,6 +335,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
|
||||
final boolean isAfterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position);
|
||||
final boolean pkgContext = JavaCompletionUtil.inSomePackage(position);
|
||||
final PsiType[] expectedTypes = ExpectedTypesGetter.getExpectedTypes(parameters.getPosition(), true);
|
||||
LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
@Override
|
||||
public void consume(final PsiReference reference, final CompletionResultSet result) {
|
||||
@@ -348,6 +366,22 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
!((PsiJavaCodeReferenceCodeFragment)originalFile).isClassesAccepted() && item != null) {
|
||||
item.setTailType(TailType.NONE);
|
||||
}
|
||||
if (item instanceof JavaMethodCallElement) {
|
||||
JavaMethodCallElement call = (JavaMethodCallElement)item;
|
||||
final PsiMethod method = call.getObject();
|
||||
if (method.getTypeParameters().length > 0) {
|
||||
final PsiType returned = TypeConversionUtil.erasure(method.getReturnType());
|
||||
PsiType matchingExpectation = returned == null ? null : ContainerUtil.find(expectedTypes, new Condition<PsiType>() {
|
||||
@Override
|
||||
public boolean value(PsiType type) {
|
||||
return type.isAssignableFrom(returned);
|
||||
}
|
||||
});
|
||||
if (matchingExpectation != null && SmartCompletionDecorator.hasUnboundTypeParams(method, matchingExpectation)) {
|
||||
call.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, matchingExpectation), position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.addElement(element);
|
||||
}
|
||||
@@ -408,24 +442,14 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
};
|
||||
|
||||
PsiElement position = parameters.getPosition();
|
||||
final Set<LookupElement> lookupSet = new LinkedHashSet<LookupElement>();
|
||||
final Set<CompletionVariant> keywordVariants = new HashSet<CompletionVariant>();
|
||||
final JavaCompletionData completionData = getCompletionData(PsiUtil.getLanguageLevel(position));
|
||||
completionData.addKeywordVariants(keywordVariants, position, parameters.getOriginalFile());
|
||||
completionData.completeKeywordsBySet(lookupSet, keywordVariants, position, result.getPrefixMatcher(), parameters.getOriginalFile());
|
||||
completionData.fillCompletions(parameters, noMiddleMatches);
|
||||
|
||||
for (final LookupElement item : lookupSet) {
|
||||
noMiddleMatches.consume(item);
|
||||
}
|
||||
JavaKeywordCompletion.addKeywords(parameters, noMiddleMatches);
|
||||
}
|
||||
|
||||
static boolean isClassNamePossible(CompletionParameters parameters) {
|
||||
boolean isSecondCompletion = parameters.getInvocationCount() >= 2;
|
||||
|
||||
PsiElement position = parameters.getPosition();
|
||||
if (JavaCompletionData.isInstanceofPlace(position)) return false;
|
||||
if (JavaKeywordCompletion.isInstanceofPlace(position)) return false;
|
||||
|
||||
final PsiElement parent = position.getParent();
|
||||
if (!(parent instanceof PsiJavaCodeReferenceElement)) return isSecondCompletion;
|
||||
@@ -452,7 +476,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (JavaCompletionData.isAfterPrimitiveOrArrayType(position)) {
|
||||
if (JavaKeywordCompletion.isAfterPrimitiveOrArrayType(position)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -466,7 +490,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement,
|
||||
CompletionParameters parameters) {
|
||||
PsiNameValuePair pair = PsiTreeUtil.getParentOfType(insertedElement, PsiNameValuePair.class);
|
||||
PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)ObjectUtils.assertNotNull(pair).getParent();
|
||||
PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)assertNotNull(pair).getParent();
|
||||
PsiAnnotation anno = (PsiAnnotation)parameterList.getParent();
|
||||
boolean showClasses = psiElement().afterLeaf("(").accepts(insertedElement);
|
||||
PsiClass annoClass = null;
|
||||
@@ -487,7 +511,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
for (final LookupElement element : set) {
|
||||
result.addElement(element);
|
||||
}
|
||||
addAllClasses(parameters, result, new InheritorsHolder(insertedElement, result));
|
||||
addAllClasses(parameters, result, new InheritorsHolder(result));
|
||||
}
|
||||
|
||||
if (annoClass != null) {
|
||||
@@ -688,10 +712,6 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
|
||||
final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false);
|
||||
if (ref != null && !(ref instanceof PsiReferenceExpression)) {
|
||||
if (ref.getParent() instanceof PsiTypeElement) {
|
||||
context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";");
|
||||
}
|
||||
|
||||
if (JavaSmartCompletionContributor.AFTER_NEW.accepts(ref)) {
|
||||
final PsiReferenceParameterList paramList = ref.getParameterList();
|
||||
if (paramList != null && paramList.getTextLength() > 0) {
|
||||
@@ -755,7 +775,7 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
if (iterator.atEnd()) return false;
|
||||
|
||||
return iterator.getTokenType() == JavaTokenType.EQ || iterator.getTokenType() == JavaTokenType.LPARENTH;
|
||||
return iterator.getTokenType() == JavaTokenType.EQ; // <caret> foo = something, we don't want the reference to be treated as a type
|
||||
}
|
||||
|
||||
private static void autoImport(@NotNull final PsiFile file, int offset, @NotNull final Editor editor) {
|
||||
|
||||
@@ -73,12 +73,12 @@ public class JavaCompletionSorting {
|
||||
}
|
||||
|
||||
List<LookupElementWeigher> afterPrefix = ContainerUtil.newArrayList();
|
||||
afterPrefix.add(new PreferByKindWeigher(type, position));
|
||||
if (!smart) {
|
||||
ContainerUtil.addIfNotNull(afterPrefix, preferStatics(position, expectedTypes));
|
||||
}
|
||||
afterPrefix.add(new PreferByKindWeigher(type, position));
|
||||
if (!smart && !afterNew) {
|
||||
afterPrefix.add(new PreferExpected(false, expectedTypes));
|
||||
if (!afterNew) {
|
||||
afterPrefix.add(new PreferExpected(false, expectedTypes));
|
||||
}
|
||||
}
|
||||
ContainerUtil.addIfNotNull(afterPrefix, recursion(parameters, expectedTypes));
|
||||
Collections.addAll(afterPrefix, new PreferSimilarlyEnding(expectedTypes),
|
||||
|
||||
+2
-1
@@ -44,7 +44,8 @@ public class JavaCompletionStatistician extends CompletionStatistician{
|
||||
return StatisticsInfo.EMPTY;
|
||||
}
|
||||
|
||||
if (SUPER_CALL.accepts(location.getCompletionParameters().getPosition())) {
|
||||
PsiElement position = location.getCompletionParameters().getPosition();
|
||||
if (SUPER_CALL.accepts(position) || ReferenceExpressionCompletionContributor.IN_SWITCH_LABEL.accepts(position)) {
|
||||
return StatisticsInfo.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.codeInsight.completion.ReferenceExpressionCompletionContributor.*;
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
public class JavaCompletionUtil {
|
||||
@@ -240,7 +241,7 @@ public class JavaCompletionUtil {
|
||||
public static List<? extends PsiElement> getAllPsiElements(final LookupElement item) {
|
||||
List<PsiMethod> allMethods = getAllMethods(item);
|
||||
if (allMethods != null) return allMethods;
|
||||
if (item.getObject() instanceof PsiElement) return Arrays.asList((PsiElement)item.getObject());
|
||||
if (item.getObject() instanceof PsiElement) return Collections.singletonList((PsiElement)item.getObject());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -498,15 +499,14 @@ public class JavaCompletionUtil {
|
||||
@NotNull LookupElement item,
|
||||
@NotNull Object object,
|
||||
@NotNull PsiElement place) {
|
||||
if (object instanceof PsiMember &&
|
||||
Java15APIUsageInspectionBase.isForbiddenApiUsage((PsiMember)object, PsiUtil.getLanguageLevel(place))) {
|
||||
return LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
if (shouldMarkRed(object, place)) {
|
||||
return PrioritizedLookupElement.withExplicitProximity(LookupElementDecorator.withRenderer(item, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
@Override
|
||||
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
|
||||
element.getDelegate().renderElement(presentation);
|
||||
presentation.setItemTextForeground(JBColor.RED);
|
||||
}
|
||||
});
|
||||
}), -1);
|
||||
}
|
||||
if (containsMember(qualifierType, object)) {
|
||||
LookupElementRenderer<LookupElementDecorator<LookupElement>> boldRenderer =
|
||||
@@ -522,6 +522,16 @@ public class JavaCompletionUtil {
|
||||
return item;
|
||||
}
|
||||
|
||||
private static boolean shouldMarkRed(@NotNull Object object, @NotNull PsiElement place) {
|
||||
if (!(object instanceof PsiMember)) return false;
|
||||
if (Java15APIUsageInspectionBase.isForbiddenApiUsage((PsiMember)object, PsiUtil.getLanguageLevel(place))) return true;
|
||||
|
||||
if (object instanceof PsiEnumConstant) {
|
||||
return findConstantsUsedInSwitch(place).contains(CompletionUtil.getOriginalOrSelf((PsiEnumConstant)object));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) {
|
||||
if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { //length and clone()
|
||||
PsiFile file = ((PsiMember)object).getContainingFile();
|
||||
@@ -542,17 +552,6 @@ public class JavaCompletionUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static LookupElement highlight(LookupElement decorator) {
|
||||
return PrioritizedLookupElement.withExplicitProximity(
|
||||
LookupElementDecorator.withRenderer(decorator, new LookupElementRenderer<LookupElementDecorator<LookupElement>>() {
|
||||
@Override
|
||||
public void renderElement(LookupElementDecorator<LookupElement> element, LookupElementPresentation presentation) {
|
||||
element.getDelegate().renderElement(presentation);
|
||||
presentation.setItemTextBold(true);
|
||||
}
|
||||
}), 1);
|
||||
}
|
||||
|
||||
private static List<? extends LookupElement> createLookupElements(CompletionElement completionElement, PsiJavaReference reference) {
|
||||
Object completion = completionElement.getElement();
|
||||
assert !(completion instanceof LookupElement);
|
||||
@@ -560,7 +559,7 @@ public class JavaCompletionUtil {
|
||||
if (reference instanceof PsiJavaCodeReferenceElement) {
|
||||
if (completion instanceof PsiMethod &&
|
||||
((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiImportStaticStatement) {
|
||||
return Arrays.asList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY));
|
||||
return Collections.singletonList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
|
||||
if (completion instanceof PsiClass) {
|
||||
@@ -572,7 +571,7 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
|
||||
if (reference instanceof PsiMethodReferenceExpression && completion instanceof PsiMethod && ((PsiMethod)completion).isConstructor()) {
|
||||
return Arrays.asList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, "new", PsiSubstitutor.EMPTY, null));
|
||||
return Collections.singletonList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, "new", PsiSubstitutor.EMPTY, null));
|
||||
}
|
||||
|
||||
LookupElement _ret = LookupItemUtil.objectToLookupItem(completion);
|
||||
@@ -583,7 +582,7 @@ public class JavaCompletionUtil {
|
||||
((LookupItem<?>)_ret).setAttribute(LookupItem.SUBSTITUTOR, substitutor);
|
||||
}
|
||||
|
||||
return Arrays.asList(_ret);
|
||||
return Collections.singletonList(_ret);
|
||||
}
|
||||
|
||||
public static boolean hasAccessibleConstructor(PsiType type) {
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
|
||||
result.addElement(item);
|
||||
}
|
||||
|
||||
JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(position, result));
|
||||
JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(result));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ public class JavaGenerateMemberCompletionContributor {
|
||||
|
||||
PsiElement position = parameters.getPosition();
|
||||
if (psiElement(PsiIdentifier.class).withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiClass.class).
|
||||
andNot(JavaCompletionData.AFTER_DOT).
|
||||
andNot(JavaKeywordCompletion.AFTER_DOT).
|
||||
andNot(psiElement().afterLeaf(psiElement().inside(PsiModifierList.class))).accepts(position)) {
|
||||
suggestGeneratedMethods(result, position);
|
||||
} else if (psiElement(PsiIdentifier.class)
|
||||
|
||||
+136
-224
@@ -19,16 +19,14 @@ import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.TailTypes;
|
||||
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.LambdaHighlightingUtil;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiJavaElementPattern;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.*;
|
||||
import com.intellij.psi.filters.classes.EnumOrAnnotationTypeFilter;
|
||||
import com.intellij.psi.filters.classes.InterfaceFilter;
|
||||
import com.intellij.psi.filters.getters.JavaMembersGetter;
|
||||
import com.intellij.psi.filters.position.*;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspClassLevelDeclarationStatement;
|
||||
@@ -38,28 +36,18 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
import static com.intellij.patterns.StandardPatterns.not;
|
||||
|
||||
public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
private static final @NonNls String[] BLOCK_FINALIZERS = {"{", "}", ";", ":", "else"};
|
||||
|
||||
public class JavaKeywordCompletion {
|
||||
public static final ElementPattern<PsiElement> AFTER_DOT = psiElement().afterLeaf(".");
|
||||
|
||||
public static final PsiJavaElementPattern.Capture<PsiElement> VARIABLE_AFTER_FINAL =
|
||||
psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class);
|
||||
static final ElementPattern<PsiElement> VARIABLE_AFTER_FINAL = psiElement().afterLeaf(PsiKeyword.FINAL).inside(PsiDeclarationStatement.class);
|
||||
|
||||
public static final LeftNeighbour AFTER_TRY_BLOCK = new LeftNeighbour(new AndFilter(
|
||||
new TextFilter("}"),
|
||||
new ParentElementFilter(new AndFilter(
|
||||
new LeftNeighbour(new TextFilter(PsiKeyword.TRY)),
|
||||
new ParentElementFilter(new ClassFilter(PsiTryStatement.class)))
|
||||
)));
|
||||
|
||||
private static final PsiJavaElementPattern.Capture<PsiElement> INSIDE_PARAMETER_LIST =
|
||||
private static final ElementPattern<PsiElement> INSIDE_PARAMETER_LIST =
|
||||
psiElement().withParent(
|
||||
psiElement(PsiJavaCodeReferenceElement.class).insideStarting(
|
||||
psiElement().withTreeParent(
|
||||
@@ -98,7 +86,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
new LeftNeighbour(
|
||||
new OrFilter(
|
||||
new AndFilter (
|
||||
new TextFilter(BLOCK_FINALIZERS),
|
||||
new TextFilter("{", "}", ";", ":", "else"),
|
||||
new NotFilter (
|
||||
new SuperParentFilter(new ClassFilter(PsiAnnotation.class))
|
||||
)
|
||||
@@ -151,10 +139,10 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
};
|
||||
|
||||
public static final ElementPattern<PsiElement> START_FOR =
|
||||
static final ElementPattern<PsiElement> START_FOR =
|
||||
psiElement().afterLeaf(psiElement().withText("(").afterLeaf("for")).withParents(PsiJavaCodeReferenceElement.class,
|
||||
PsiExpressionStatement.class, PsiForStatement.class);
|
||||
private static final PsiJavaElementPattern.Capture<PsiElement> CLASS_REFERENCE =
|
||||
private static final ElementPattern<PsiElement> CLASS_REFERENCE =
|
||||
psiElement().withParent(psiReferenceExpression().referencing(psiClass().andNot(psiElement(PsiTypeParameter.class))));
|
||||
|
||||
private static final ElementPattern<PsiElement> EXPR_KEYWORDS = and(
|
||||
@@ -170,18 +158,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
not(psiElement().afterLeaf("."))
|
||||
);
|
||||
|
||||
public JavaCompletionData(){
|
||||
declareCompletionSpaces();
|
||||
|
||||
initVariantsInFileScope();
|
||||
initVariantsInClassScope();
|
||||
initVariantsInMethodScope();
|
||||
|
||||
defineScopeEquivalence(PsiMethod.class, PsiClassInitializer.class);
|
||||
defineScopeEquivalence(PsiMethod.class, JavaCodeFragment.class);
|
||||
}
|
||||
|
||||
public static final NotNullLazyValue<ElementPattern<PsiElement>> DECLARATION_START = new NotNullLazyValue<ElementPattern<PsiElement>>() {
|
||||
static final NotNullLazyValue<ElementPattern<PsiElement>> DECLARATION_START = new NotNullLazyValue<ElementPattern<PsiElement>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected ElementPattern<PsiElement> compute() {
|
||||
@@ -200,170 +177,6 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
};
|
||||
|
||||
private void declareCompletionSpaces() {
|
||||
declareFinalScope(PsiFile.class);
|
||||
|
||||
{
|
||||
// Class body
|
||||
final CompletionVariant variant = new CompletionVariant(CLASS_BODY.getValue());
|
||||
variant.includeScopeClass(PsiClass.class, true);
|
||||
registerVariant(variant);
|
||||
}
|
||||
{
|
||||
// Method body
|
||||
final CompletionVariant variant = new CompletionVariant(new AndFilter(new InsideElementFilter(new ClassFilter(PsiCodeBlock.class)),
|
||||
new NotFilter(new InsideElementFilter(new ClassFilter(JspClassLevelDeclarationStatement.class)))));
|
||||
variant.includeScopeClass(PsiMethod.class, true);
|
||||
variant.includeScopeClass(PsiClassInitializer.class, true);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
{
|
||||
// Field initializer
|
||||
final CompletionVariant variant = new CompletionVariant(new AfterElementFilter(new TextFilter("=")));
|
||||
variant.includeScopeClass(PsiField.class, true);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
declareFinalScope(PsiLiteralExpression.class);
|
||||
declareFinalScope(PsiComment.class);
|
||||
}
|
||||
|
||||
protected void initVariantsInFileScope(){
|
||||
}
|
||||
|
||||
/**
|
||||
* aClass == null for JspDeclaration scope
|
||||
*/
|
||||
protected void initVariantsInClassScope() {
|
||||
// Completion for extends keyword
|
||||
// position
|
||||
{
|
||||
final ElementFilter position = new AndFilter(
|
||||
new NotFilter(CLASS_BODY.getValue()),
|
||||
new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.EXTENDS)))),
|
||||
new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.IMPLEMENTS)))),
|
||||
new NotFilter(new LeftNeighbour(new LeftNeighbour(new TextFilter("<", ",")))),
|
||||
new NotFilter(new ScopeFilter(new EnumOrAnnotationTypeFilter())),
|
||||
new LeftNeighbour(new OrFilter(
|
||||
new ClassFilter(PsiIdentifier.class),
|
||||
new TextFilter(">"))));
|
||||
// completion
|
||||
final CompletionVariant variant = new CompletionVariant(position);
|
||||
variant.includeScopeClass(PsiClass.class, true);
|
||||
variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
variant.excludeScopeClass(PsiAnonymousClass.class);
|
||||
variant.excludeScopeClass(PsiTypeParameter.class);
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
// Completion for implements keyword
|
||||
// position
|
||||
{
|
||||
final ElementFilter position = new AndFilter(
|
||||
new NotFilter(CLASS_BODY.getValue()),
|
||||
new NotFilter(new BeforeElementFilter(new ContentFilter(new TextFilter(PsiKeyword.EXTENDS)))),
|
||||
new NotFilter(new AfterElementFilter(new ContentFilter(new TextFilter(PsiKeyword.IMPLEMENTS)))),
|
||||
new NotFilter(new LeftNeighbour(new LeftNeighbour(new TextFilter("<", ",")))),
|
||||
new LeftNeighbour(new OrFilter(
|
||||
new ClassFilter(PsiIdentifier.class),
|
||||
new TextFilter(">"))),
|
||||
new NotFilter(new ScopeFilter(new InterfaceFilter())));
|
||||
// completion
|
||||
final CompletionVariant variant = new CompletionVariant(position);
|
||||
variant.includeScopeClass(PsiClass.class, true);
|
||||
variant.addCompletion(PsiKeyword.IMPLEMENTS, TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
variant.excludeScopeClass(PsiAnonymousClass.class);
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
final CompletionVariant variant = new CompletionVariant(PsiElement.class, psiElement().afterLeaf(
|
||||
psiElement(PsiIdentifier.class).afterLeaf(
|
||||
psiElement().withText(string().oneOf(",", "<")).withParent(PsiTypeParameterList.class))));
|
||||
//variant.includeScopeClass(PsiClass.class, true);
|
||||
variant.addCompletion(PsiKeyword.EXTENDS, TailType.HUMBLE_SPACE_BEFORE_WORD);
|
||||
registerVariant(variant);
|
||||
}
|
||||
}
|
||||
|
||||
private void initVariantsInMethodScope() {
|
||||
// Completion for classes in method throws section
|
||||
// position
|
||||
{
|
||||
final ElementFilter position = new LeftNeighbour(new AndFilter(
|
||||
new TextFilter(")"),
|
||||
new ParentElementFilter(new ClassFilter(PsiParameterList.class))));
|
||||
|
||||
// completion
|
||||
CompletionVariant variant = new CompletionVariant(PsiMethod.class, position);
|
||||
variant.includeScopeClass(PsiClass.class); // for throws on separate line
|
||||
variant.addCompletion(PsiKeyword.THROWS);
|
||||
|
||||
registerVariant(variant);
|
||||
|
||||
//in annotation methods
|
||||
variant = new CompletionVariant(PsiAnnotationMethod.class, position);
|
||||
variant.addCompletion(PsiKeyword.DEFAULT);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
{
|
||||
// Keyword completion in returns !!!!
|
||||
final CompletionVariant variant = new CompletionVariant(PsiMethod.class, new LeftNeighbour(new TextFilter(PsiKeyword.RETURN)));
|
||||
variant.addCompletion(PsiKeyword.TRUE, TailType.NONE);
|
||||
variant.addCompletion(PsiKeyword.FALSE, TailType.NONE);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
|
||||
// Catch/Finally completion
|
||||
{
|
||||
final ElementFilter position = AFTER_TRY_BLOCK;
|
||||
|
||||
final CompletionVariant variant = new CompletionVariant(position);
|
||||
variant.includeScopeClass(PsiCodeBlock.class, true);
|
||||
variant.addCompletion(PsiKeyword.CATCH, TailTypes.CATCH_LPARENTH);
|
||||
variant.addCompletion(PsiKeyword.FINALLY, TailTypes.FINALLY_LBRACE);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
// Catch/Finally completion
|
||||
{
|
||||
final ElementFilter position = new LeftNeighbour(new AndFilter(
|
||||
new TextFilter("}"),
|
||||
new ParentElementFilter(new AndFilter(
|
||||
new LeftNeighbour(new NotFilter(new TextFilter(PsiKeyword.TRY))),
|
||||
new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiTryStatement.class)),
|
||||
new ParentElementFilter(new ClassFilter(PsiCatchSection.class)))
|
||||
))));
|
||||
|
||||
final CompletionVariant variant = new CompletionVariant(position);
|
||||
variant.includeScopeClass(PsiCodeBlock.class, false);
|
||||
variant.addCompletion(PsiKeyword.CATCH, TailTypes.CATCH_LPARENTH);
|
||||
variant.addCompletion(PsiKeyword.FINALLY, TailTypes.FINALLY_LBRACE);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
// Completion for else expression
|
||||
// completion
|
||||
{
|
||||
final ElementFilter position = new LeftNeighbour(
|
||||
new OrFilter(
|
||||
new AndFilter(new TextFilter("}"),new ParentElementFilter(new ClassFilter(PsiIfStatement.class), 3)),
|
||||
new AndFilter(new TextFilter(";"),new ParentElementFilter(new ClassFilter(PsiIfStatement.class), 2))
|
||||
));
|
||||
final CompletionVariant variant = new CompletionVariant(PsiMethod.class, position);
|
||||
variant.addCompletion(PsiKeyword.ELSE);
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static TailType getReturnTail(PsiElement position) {
|
||||
PsiElement scope = position;
|
||||
while(true){
|
||||
@@ -390,7 +203,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addStatementKeywords(Consumer<LookupElement> variant, PsiElement position) {
|
||||
private static void addStatementKeywords(Consumer<LookupElement> variant, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.SWITCH), TailTypes.SWITCH_LPARENTH));
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.WHILE), TailTypes.WHILE_LPARENTH));
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DO), TailTypes.DO_LBRACE));
|
||||
@@ -411,19 +224,82 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
ret = new OverrideableSpace(ret, returnTail);
|
||||
}
|
||||
variant.consume(ret);
|
||||
|
||||
if (psiElement().withText(";").withSuperParent(2, PsiIfStatement.class).accepts(prevLeaf) ||
|
||||
psiElement().withText("}").withSuperParent(3, PsiIfStatement.class).accepts(prevLeaf)) {
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.ELSE), TailTypes.SYNCHRONIZED_LPARENTH));
|
||||
}
|
||||
|
||||
if (psiElement().withText("}").withParent(psiElement(PsiCodeBlock.class).withParent(or(psiElement(PsiTryStatement.class), psiElement(PsiCatchSection.class)))).accepts(prevLeaf)) {
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.CATCH), TailTypes.CATCH_LPARENTH));
|
||||
variant.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.FINALLY), TailTypes.FINALLY_LBRACE));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fillCompletions(CompletionParameters parameters, final Consumer<LookupElement> result) {
|
||||
static void addKeywords(CompletionParameters parameters, final Consumer<LookupElement> result) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) {
|
||||
if (PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(position);
|
||||
addFinal(result, position, prevLeaf);
|
||||
|
||||
if (isStatementPosition(position)) {
|
||||
addCaseDefault(result, position);
|
||||
if (START_SWITCH.accepts(position)) {
|
||||
return;
|
||||
}
|
||||
|
||||
addBreakContinue(result, position);
|
||||
addStatementKeywords(result, position, prevLeaf);
|
||||
}
|
||||
|
||||
addThisSuper(result, position);
|
||||
|
||||
addExpressionKeywords(parameters, result, position, prevLeaf);
|
||||
|
||||
addFileHeaderKeywords(result, position, prevLeaf);
|
||||
|
||||
addInstanceof(result, position);
|
||||
|
||||
addClassKeywords(result, position, prevLeaf);
|
||||
|
||||
addMethodHeaderKeywords(result, position, prevLeaf);
|
||||
|
||||
addPrimitiveTypes(result, position);
|
||||
|
||||
addClassLiteral(result, position);
|
||||
|
||||
addUnfinishedMethodTypeParameters(position, result);
|
||||
|
||||
addExtendsSuperImplements(result, position, prevLeaf);
|
||||
}
|
||||
|
||||
private static void addMethodHeaderKeywords(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
if (psiElement().withText(")").withParents(PsiParameterList.class, PsiMethod.class).accepts(prevLeaf)) {
|
||||
assert prevLeaf != null;
|
||||
if (prevLeaf.getParent().getParent() instanceof PsiAnnotationMethod) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
} else {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.THROWS), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addCaseDefault(Consumer<LookupElement> result, PsiElement position) {
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class) != null) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.CASE), TailType.INSERT_SPACE));
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.CASE_COLON));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFinal(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
PsiStatement statement = PsiTreeUtil.getParentOfType(position, PsiExpressionStatement.class);
|
||||
if (statement == null) {
|
||||
statement = PsiTreeUtil.getParentOfType(position, PsiDeclarationStatement.class);
|
||||
}
|
||||
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(position);
|
||||
if (statement != null && statement.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) {
|
||||
if (!psiElement().withSuperParent(2, PsiSwitchStatement.class).afterLeaf("{").accepts(statement)) {
|
||||
PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(prevLeaf, PsiTryStatement.class);
|
||||
@@ -433,19 +309,15 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
}
|
||||
|
||||
if (isStatementPosition(position)) {
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class) != null) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.CASE), TailType.INSERT_SPACE));
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.CASE_COLON));
|
||||
if (START_SWITCH.accepts(position)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addBreakContinue(result, position);
|
||||
addStatementKeywords(result, position);
|
||||
if ((isInsideParameterList(position) || isAtResourceVariableStart(position) || isAtCatchVariableStart(position)) &&
|
||||
!psiElement().afterLeaf(PsiKeyword.FINAL).accepts(position) &&
|
||||
!AFTER_DOT.accepts(position)) {
|
||||
result.consume(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void addThisSuper(Consumer<LookupElement> result, PsiElement position) {
|
||||
if (SUPER_OR_THIS_PATTERN.accepts(position)) {
|
||||
final boolean afterDot = AFTER_DOT.accepts(position);
|
||||
final boolean insideQualifierClass = isInsideQualifierClass(position);
|
||||
@@ -477,6 +349,15 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
result.consume(superItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExpressionKeywords(CompletionParameters parameters, Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
if (psiElement(JavaTokenType.DOUBLE_COLON).accepts(prevLeaf)) {
|
||||
PsiMethodReferenceExpression parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiMethodReferenceExpression.class);
|
||||
TailType tail = parent != null && !LambdaHighlightingUtil.insertSemicolon(parent.getParent()) ? TailType.SEMICOLON : TailType.NONE;
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.NEW), tail));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isExpressionPosition(position)) {
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) == null) {
|
||||
@@ -488,7 +369,9 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
result.consume(createKeyword(position, PsiKeyword.FALSE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFileHeaderKeywords(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
PsiFile file = position.getContainingFile();
|
||||
if (!(file instanceof PsiExpressionCodeFragment) &&
|
||||
!(file instanceof PsiJavaCodeReferenceCodeFragment) &&
|
||||
@@ -502,12 +385,12 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
}
|
||||
|
||||
if ((isInsideParameterList(position) || isAtResourceVariableStart(position) || isAtCatchVariableStart(position)) &&
|
||||
!psiElement().afterLeaf(PsiKeyword.FINAL).accepts(position) &&
|
||||
!AFTER_DOT.accepts(position)) {
|
||||
result.consume(TailTypeDecorator.withTail(createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
if (PsiUtil.isLanguageLevel5OrHigher(position) && prevLeaf != null && prevLeaf.textMatches(PsiKeyword.IMPORT)) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.STATIC), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addInstanceof(Consumer<LookupElement> result, PsiElement position) {
|
||||
if (isInstanceofPlace(position)) {
|
||||
result.consume(LookupElementDecorator.withInsertHandler(
|
||||
createKeyword(position, PsiKeyword.INSTANCEOF),
|
||||
@@ -533,32 +416,65 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClassKeywords(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
if (isSuitableForClass(position)) {
|
||||
for (String s : ModifierChooser.getKeywords(position)) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, s), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(position)) {
|
||||
PsiClass containingClass = PsiTreeUtil.getParentOfType(position, PsiClass.class);
|
||||
if (containingClass != null && containingClass.isInterface()) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.DEFAULT), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.CLASS), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
if (PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, true, PsiMember.class) == null) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.INTERFACE), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
if (PsiUtil.getLanguageLevel(position).isAtLeast(LanguageLevel.JDK_1_5)) {
|
||||
if (PsiUtil.isLanguageLevel5OrHigher(position)) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.ENUM), TailType.INSERT_SPACE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addPrimitiveTypes(result, position);
|
||||
if (psiElement().withText("@").andNot(psiElement().inside(PsiParameterList.class)).andNot(psiElement().inside(psiNameValuePair()))
|
||||
.accepts(prevLeaf)) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.INTERFACE), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClassLiteral(Consumer<LookupElement> result, PsiElement position) {
|
||||
if (isAfterTypeDot(position)) {
|
||||
result.consume(createKeyword(position, PsiKeyword.CLASS));
|
||||
}
|
||||
}
|
||||
|
||||
addUnfinishedMethodTypeParameters(position, result);
|
||||
|
||||
private static void addExtendsSuperImplements(Consumer<LookupElement> result, PsiElement position, @Nullable PsiElement prevLeaf) {
|
||||
if (JavaMemberNameCompletionContributor.INSIDE_TYPE_PARAMS_PATTERN.accepts(position)) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.EXTENDS), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.SUPER), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
|
||||
if (prevLeaf == null || !(prevLeaf instanceof PsiIdentifier || prevLeaf.textMatches(">"))) return;
|
||||
|
||||
PsiClass psiClass = null;
|
||||
if (prevLeaf instanceof PsiIdentifier && prevLeaf.getParent() instanceof PsiClass) {
|
||||
psiClass = (PsiClass)prevLeaf.getParent();
|
||||
} else {
|
||||
PsiReferenceList referenceList = PsiTreeUtil.getParentOfType(prevLeaf, PsiReferenceList.class);
|
||||
if (referenceList != null && referenceList.getParent() instanceof PsiClass) {
|
||||
psiClass = (PsiClass)referenceList.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
if (psiClass != null) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.EXTENDS), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
if (!psiClass.isInterface()) {
|
||||
result.consume(new OverrideableSpace(createKeyword(position, PsiKeyword.IMPLEMENTS), TailType.HUMBLE_SPACE_BEFORE_WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean mayExpectBoolean(CompletionParameters parameters) {
|
||||
@@ -595,7 +511,7 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
|
||||
public static boolean isSuitableForClass(PsiElement position) {
|
||||
if (psiElement().afterLeaf("@").accepts(position) ||
|
||||
PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class) != null) {
|
||||
PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class, PsiExpressionCodeFragment.class) != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -736,10 +652,6 @@ public class JavaCompletionData extends JavaAwareCompletionData {
|
||||
}
|
||||
|
||||
private static boolean isStatementPosition(PsiElement position) {
|
||||
if (PsiTreeUtil.getNonStrictParentOfType(position, PsiLiteralExpression.class, PsiComment.class) != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (psiElement().withSuperParent(2, PsiConditionalExpression.class).andNot(psiElement().insideStarting(psiElement(PsiConditionalExpression.class))).accepts(position)) {
|
||||
return false;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
public class JavaNoVariantsDelegator extends CompletionContributor {
|
||||
@Override
|
||||
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
|
||||
final InheritorsHolder holder = new InheritorsHolder(parameters.getPosition(), result);
|
||||
final InheritorsHolder holder = new InheritorsHolder(result);
|
||||
ResultTracker tracker = new ResultTracker(result) {
|
||||
@Override
|
||||
public void consume(CompletionResult plainResult) {
|
||||
|
||||
+16
-18
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.*;
|
||||
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
@@ -38,10 +39,7 @@ import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
@@ -131,9 +129,11 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
|
||||
|
||||
public JavaSmartCompletionContributor() {
|
||||
extend(CompletionType.SMART, SmartCastProvider.INSIDE_TYPECAST_TYPE, new SmartCastProvider());
|
||||
extend(CompletionType.SMART, SmartCastProvider.TYPECAST_TYPE_CANDIDATE, new SmartCastProvider());
|
||||
|
||||
extend(CompletionType.SMART, SameSignatureCallParametersProvider.IN_CALL_ARGUMENT, new SameSignatureCallParametersProvider());
|
||||
|
||||
extend(CompletionType.SMART, MethodReturnTypeProvider.IN_METHOD_RETURN_TYPE, new MethodReturnTypeProvider());
|
||||
|
||||
extend(CompletionType.SMART, psiElement().afterLeaf(PsiKeyword.INSTANCEOF), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
@@ -172,6 +172,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
extend(CompletionType.SMART, psiElement(), new CompletionProvider<CompletionParameters>() {
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
if (SmartCastProvider.shouldSuggestCast(parameters)) return;
|
||||
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (reference != null) {
|
||||
@@ -215,6 +217,8 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
extend(CompletionType.SMART, INSIDE_EXPRESSION, new ExpectedTypeBasedCompletionProvider() {
|
||||
@Override
|
||||
protected void addCompletions(final CompletionParameters params, final CompletionResultSet result, final Collection<ExpectedTypeInfo> _infos) {
|
||||
if (SmartCastProvider.shouldSuggestCast(params)) return;
|
||||
|
||||
Consumer<LookupElement> noTypeCheck = decorateWithoutTypeCheck(result, _infos);
|
||||
|
||||
THashSet<ExpectedTypeInfo> mergedInfos = new THashSet<ExpectedTypeInfo>(_infos, EXPECTED_TYPE_INFO_STRATEGY);
|
||||
@@ -265,7 +269,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
@Override
|
||||
public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
final ElementPattern<? extends PsiElement> leftNeighbor = JavaCompletionData.AFTER_DOT;
|
||||
final ElementPattern<? extends PsiElement> leftNeighbor = JavaKeywordCompletion.AFTER_DOT;
|
||||
final boolean needQualify = leftNeighbor.accepts(element);
|
||||
|
||||
for (final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) {
|
||||
@@ -310,7 +314,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
final PsiCodeBlock tryBlock = context.get(tryKey).getTryBlock();
|
||||
if (tryBlock == null) return;
|
||||
|
||||
final InheritorsHolder holder = new InheritorsHolder(parameters.getPosition(), result);
|
||||
final InheritorsHolder holder = new InheritorsHolder(result);
|
||||
|
||||
for (final PsiClassType type : ExceptionUtil.getThrownExceptions(tryBlock.getStatements())) {
|
||||
PsiClass typeClass = type.resolve();
|
||||
@@ -378,7 +382,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
boolean quick,
|
||||
Consumer<LookupElement> consumer) {
|
||||
PsiElement position = params.getPosition();
|
||||
if (!JavaCompletionData.AFTER_DOT.accepts(position)) {
|
||||
if (!JavaKeywordCompletion.AFTER_DOT.accepts(position)) {
|
||||
for (ExpectedTypeInfo info : mergedInfos) {
|
||||
new JavaMembersGetter(info.getType(), params).addMembers(!quick, consumer);
|
||||
if (!info.getDefaultType().equals(info.getType())) {
|
||||
@@ -525,16 +529,10 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
PsiElement lastElement = context.getFile().findElementAt(context.getStartOffset() - 1);
|
||||
if (lastElement != null && lastElement.getText().equals("(")) {
|
||||
final PsiElement parent = lastElement.getParent();
|
||||
if (parent instanceof PsiTypeCastExpression) {
|
||||
context.setDummyIdentifier("");
|
||||
return;
|
||||
}
|
||||
if (parent instanceof PsiParenthesizedExpression) {
|
||||
context.setDummyIdentifier(CompletionUtil.DUMMY_IDENTIFIER_TRIMMED + ")" + CompletionUtil.DUMMY_IDENTIFIER_TRIMMED + " "); // to handle type cast
|
||||
return;
|
||||
}
|
||||
if (lastElement != null && lastElement.getText().equals("(") && lastElement.getParent() instanceof PsiParenthesizedExpression) {
|
||||
// don't trim dummy identifier or we won't be able to determine the type of the expression after '('
|
||||
// which is needed to insert correct cast
|
||||
return;
|
||||
}
|
||||
context.setDummyIdentifier(CompletionUtil.DUMMY_IDENTIFIER_TRIMMED);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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;
|
||||
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class MethodReturnTypeProvider extends CompletionProvider<CompletionParameters> {
|
||||
protected static final ElementPattern<PsiElement> IN_METHOD_RETURN_TYPE =
|
||||
psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiTypeElement.class, PsiMethod.class)
|
||||
.andNot(JavaKeywordCompletion.AFTER_DOT);
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull final CompletionResultSet result) {
|
||||
addProbableReturnTypes(parameters, result);
|
||||
|
||||
}
|
||||
|
||||
static void addProbableReturnTypes(@NotNull CompletionParameters parameters, final Consumer<LookupElement> consumer) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(position, PsiMethod.class);
|
||||
assert method != null;
|
||||
|
||||
final PsiTypeVisitor<PsiType> eachProcessor = new PsiTypeVisitor<PsiType>() {
|
||||
private Set<PsiType> myProcessed = ContainerUtil.newHashSet();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType visitType(PsiType type) {
|
||||
if (myProcessed.add(type)) {
|
||||
int priority = type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? 1 : 1000 - myProcessed.size();
|
||||
consumer.consume(PrioritizedLookupElement.withPriority(PsiTypeLookupItem.createLookupItem(type, position), priority));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
};
|
||||
for (PsiType type : getReturnTypeCandidates(method)) {
|
||||
eachProcessor.visitType(type);
|
||||
ExpectedTypesProvider.processAllSuperTypes(type, eachProcessor, position.getProject(), ContainerUtil.<PsiType>newHashSet());
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiType[] getReturnTypeCandidates(@NotNull PsiMethod method) {
|
||||
PsiType lub = null;
|
||||
boolean hasVoid = false;
|
||||
for (PsiReturnStatement statement : PsiUtil.findReturnStatements(method)) {
|
||||
PsiExpression value = statement.getReturnValue();
|
||||
if (value == null) {
|
||||
hasVoid = true;
|
||||
}
|
||||
else {
|
||||
PsiType type = value.getType();
|
||||
if (lub == null) {
|
||||
lub = type;
|
||||
}
|
||||
else if (type != null) {
|
||||
lub = GenericsUtil.getLeastUpperBound(lub, type, method.getManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasVoid && lub == null) {
|
||||
lub = PsiType.VOID;
|
||||
}
|
||||
if (lub instanceof PsiIntersectionType) {
|
||||
return ((PsiIntersectionType)lub).getConjuncts();
|
||||
}
|
||||
return lub == null ? PsiType.EMPTY_ARRAY : new PsiType[]{lub};
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ public class ModifierChooser {
|
||||
PsiElement prev = FilterPositionUtil.searchNonSpaceNonCommentBack(element);
|
||||
|
||||
if (parent instanceof PsiJavaFile || parent instanceof PsiClass) {
|
||||
if (prev == null || JavaCompletionData.END_OF_BLOCK.getValue().isAcceptable(element, prev.getParent())) {
|
||||
if (prev == null || JavaKeywordCompletion.END_OF_BLOCK.getValue().isAcceptable(element, prev.getParent())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-10
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiMethodPattern;
|
||||
import com.intellij.patterns.StandardPatterns;
|
||||
import com.intellij.psi.*;
|
||||
@@ -42,12 +43,12 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -74,9 +75,8 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
private ReferenceExpressionCompletionContributor() {
|
||||
}
|
||||
public static final ElementPattern<PsiElement> IN_SWITCH_LABEL =
|
||||
psiElement().withSuperParent(2, psiElement(PsiSwitchLabelStatement.class).withSuperParent(2, PsiSwitchStatement.class));
|
||||
|
||||
@NotNull
|
||||
private static ElementFilter getReferenceFilter(PsiElement element, boolean allowRecursion) {
|
||||
@@ -125,7 +125,7 @@ public class ReferenceExpressionCompletionContributor {
|
||||
public static Runnable fillCompletionVariants(final JavaSmartCompletionParameters parameters, final Consumer<LookupElement> result) {
|
||||
final PsiElement element = parameters.getPosition();
|
||||
if (JavaSmartCompletionContributor.INSIDE_TYPECAST_EXPRESSION.accepts(element)) return null;
|
||||
if (JavaCompletionData.isAfterPrimitiveOrArrayType(element)) return null;
|
||||
if (JavaKeywordCompletion.isAfterPrimitiveOrArrayType(element)) return null;
|
||||
|
||||
final int offset = parameters.getParameters().getOffset();
|
||||
final PsiReference reference = element.getContainingFile().findReferenceAt(offset);
|
||||
@@ -219,10 +219,11 @@ public class ReferenceExpressionCompletionContributor {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static Set<PsiField> findConstantsUsedInSwitch(PsiElement element) {
|
||||
final Set<PsiField> used = new HashSet<PsiField>();
|
||||
if (psiElement().withSuperParent(2, psiElement(PsiSwitchLabelStatement.class).withSuperParent(2, PsiSwitchStatement.class)).accepts(element)) {
|
||||
PsiSwitchStatement sw = PsiTreeUtil.getParentOfType(element, PsiSwitchStatement.class);
|
||||
@NotNull
|
||||
public static Set<PsiField> findConstantsUsedInSwitch(@Nullable PsiElement position) {
|
||||
if (IN_SWITCH_LABEL.accepts(position)) {
|
||||
Set<PsiField> used = ContainerUtil.newLinkedHashSet();
|
||||
PsiSwitchStatement sw = PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class);
|
||||
assert sw != null;
|
||||
final PsiCodeBlock body = sw.getBody();
|
||||
assert body != null;
|
||||
@@ -237,8 +238,9 @@ public class ReferenceExpressionCompletionContributor {
|
||||
}
|
||||
}
|
||||
}
|
||||
return used;
|
||||
}
|
||||
return used;
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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.RParenthTailType;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
@@ -11,31 +12,63 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiEmptyExpressionImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class SmartCastProvider extends CompletionProvider<CompletionParameters> {
|
||||
static final PsiElementPattern.Capture<PsiElement> INSIDE_TYPECAST_TYPE = PlatformPatterns.psiElement().afterLeaf(
|
||||
PlatformPatterns.psiElement().withText("(").withParent(
|
||||
PsiTypeCastExpression.class));
|
||||
static final ElementPattern<PsiElement> TYPECAST_TYPE_CANDIDATE = psiElement().afterLeaf("(");
|
||||
|
||||
static boolean shouldSuggestCast(CompletionParameters parameters) {
|
||||
PsiElement position = parameters.getPosition();
|
||||
PsiElement parent = getParenthesisOwner(position);
|
||||
if (parent instanceof PsiTypeCastExpression) return true;
|
||||
if (parent instanceof PsiParenthesizedExpression) {
|
||||
return parameters.getOffset() == position.getTextRange().getStartOffset();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiElement getParenthesisOwner(PsiElement position) {
|
||||
PsiElement lParen = PsiTreeUtil.prevVisibleLeaf(position);
|
||||
return lParen == null || !lParen.textMatches("(") ? null : lParen.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) {
|
||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
final PsiElement originalPosition = parameters.getOriginalPosition();
|
||||
final boolean overwrite = INSIDE_TYPECAST_TYPE.accepts(originalPosition);
|
||||
addCastVariants(parameters, result);
|
||||
}
|
||||
|
||||
static void addCastVariants(@NotNull CompletionParameters parameters, @NotNull Consumer<LookupElement> result) {
|
||||
if (!shouldSuggestCast(parameters)) return;
|
||||
|
||||
PsiElement position = parameters.getPosition();
|
||||
PsiElement parenthesisOwner = getParenthesisOwner(position);
|
||||
final boolean insideCast = parenthesisOwner instanceof PsiTypeCastExpression;
|
||||
|
||||
if (insideCast) {
|
||||
PsiElement parent = parenthesisOwner.getParent();
|
||||
if (parent instanceof PsiParenthesizedExpression && parent.getParent() instanceof PsiReferenceExpression) {
|
||||
for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiParenthesizedExpression)parent, false)) {
|
||||
result.consume(PsiTypeLookupItem.createLookupItem(info.getType(), parent));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||
PsiType type = info.getDefaultType();
|
||||
if (type instanceof PsiWildcardType) {
|
||||
type = ((PsiWildcardType)type).getBound();
|
||||
@@ -45,42 +78,34 @@ class SmartCastProvider extends CompletionProvider<CompletionParameters> {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.addElement(createSmartCastElement(parameters, overwrite, type));
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
final PsiType castedType = getCastedExpressionType(originalPosition);
|
||||
final PsiType castedType = getCastedExpressionType(parenthesisOwner);
|
||||
if (castedType != null && !(castedType instanceof PsiPrimitiveType)) {
|
||||
final PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(originalPosition);
|
||||
final PsiClassType boxedType = ((PsiPrimitiveType)type).getBoxedType(position);
|
||||
if (boxedType != null) {
|
||||
result.addElement(createSmartCastElement(parameters, overwrite, boxedType));
|
||||
type = boxedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.consume(createSmartCastElement(parameters, insideCast, type));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType getCastedExpressionType(PsiElement originalPosition) {
|
||||
if (INSIDE_TYPECAST_TYPE.accepts(originalPosition)) {
|
||||
final PsiTypeCastExpression cast = PsiTreeUtil.getParentOfType(originalPosition, PsiTypeCastExpression.class);
|
||||
if (cast != null) {
|
||||
final PsiExpression operand = cast.getOperand();
|
||||
return operand == null ? null : operand.getType();
|
||||
}
|
||||
private static PsiType getCastedExpressionType(PsiElement parenthesisOwner) {
|
||||
if (parenthesisOwner instanceof PsiTypeCastExpression) {
|
||||
final PsiExpression operand = ((PsiTypeCastExpression)parenthesisOwner).getOperand();
|
||||
return operand == null ? null : operand.getType();
|
||||
}
|
||||
final PsiParenthesizedExpression parens = PsiTreeUtil.getParentOfType(originalPosition, PsiParenthesizedExpression.class, true, PsiStatement.class);
|
||||
if (parens != null) {
|
||||
final PsiExpression rightSide = parens.getExpression();
|
||||
if (rightSide != null) {
|
||||
return rightSide.getType();
|
||||
}
|
||||
PsiElement next = parens.getNextSibling();
|
||||
|
||||
if (parenthesisOwner instanceof PsiParenthesizedExpression) {
|
||||
PsiElement next = parenthesisOwner.getNextSibling();
|
||||
while (next != null && (next instanceof PsiEmptyExpressionImpl || next instanceof PsiErrorElement || next instanceof PsiWhiteSpace)) {
|
||||
next = next.getNextSibling();
|
||||
}
|
||||
if (next instanceof PsiExpression) {
|
||||
return ((PsiExpression)next).getType();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -111,7 +136,9 @@ class SmartCastProvider extends CompletionProvider<CompletionParameters> {
|
||||
context.setTailOffset(TailType.insertChar(editor, context.getTailOffset(), ' '));
|
||||
}
|
||||
|
||||
editor.getCaretModel().moveToOffset(context.getTailOffset());
|
||||
if (parameters.getCompletionType() == CompletionType.SMART) {
|
||||
editor.getCaretModel().moveToOffset(context.getTailOffset());
|
||||
}
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
});
|
||||
|
||||
+6
-14
@@ -23,9 +23,9 @@ import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -177,20 +177,12 @@ public class SmartCompletionDecorator extends TailTypeDecorator<LookupElement> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PsiSubstitutor calculateMethodReturnTypeSubstitutor(PsiMethod method, final PsiType expected) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
|
||||
PsiResolveHelper helper = JavaPsiFacade.getInstance(method.getProject()).getResolveHelper();
|
||||
final PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
PsiType substitution = helper.getSubstitutionForTypeParameter(typeParameter, method.getReturnType(), expected,
|
||||
false, PsiUtil.getLanguageLevel(method));
|
||||
if (PsiType.NULL.equals(substitution)) {
|
||||
substitution = TypeConversionUtil.typeParameterErasure(typeParameter);
|
||||
}
|
||||
public static PsiSubstitutor calculateMethodReturnTypeSubstitutor(@NotNull PsiMethod method, @NotNull final PsiType expected) {
|
||||
PsiType returnType = method.getReturnType();
|
||||
if (returnType == null) return PsiSubstitutor.EMPTY;
|
||||
|
||||
substitutor = substitutor.put(typeParameter, substitution);
|
||||
}
|
||||
return substitutor;
|
||||
PsiResolveHelper helper = JavaPsiFacade.getInstance(method.getProject()).getResolveHelper();
|
||||
return helper.inferTypeArguments(method.getTypeParameters(), new PsiType[]{expected}, new PsiType[]{returnType}, LanguageLevel.HIGHEST);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+22
-3
@@ -16,18 +16,20 @@
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.openapi.roots.ExternalLibraryDescriptor;
|
||||
import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ExternalLibraryDescriptor;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.intellij.lang.annotations.Flow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,17 +41,34 @@ public class JetBrainsAnnotationsExternalLibraryResolver extends ExternalLibrary
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getLibraryClassesRoots() {
|
||||
return Collections.singletonList(FileUtil.toSystemIndependentName(new File(PathManager.getLibPath(), "annotations.jar").getAbsolutePath()));
|
||||
File annotationsJar = new File(PathManager.getLibPath(), "annotations.jar");
|
||||
if (annotationsJar.exists()) {
|
||||
return Collections.singletonList(FileUtil.toSystemIndependentName(annotationsJar.getAbsolutePath()));
|
||||
}
|
||||
return getPathsToAnnotationsDirectoriesInDevelopmentMode("annotations");
|
||||
}
|
||||
};
|
||||
|
||||
private static final ExternalLibraryDescriptor JAVA8 = new JetBrainsAnnotationsLibraryDescriptor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getLibraryClassesRoots() {
|
||||
return Collections.singletonList(FileUtil.toSystemIndependentName(new File(PathManager.getHomePath(), "redist/annotations-java8.jar").getAbsolutePath()));
|
||||
File annotationsJar = new File(PathManager.getHomePath(), "redist/annotations-java8.jar");
|
||||
if (annotationsJar.exists()) {
|
||||
return Collections.singletonList(FileUtil.toSystemIndependentName(annotationsJar.getAbsolutePath()));
|
||||
}
|
||||
return getPathsToAnnotationsDirectoriesInDevelopmentMode("annotations-java8");
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static List<String> getPathsToAnnotationsDirectoriesInDevelopmentMode(final String moduleName) {
|
||||
final String annotationsRoot = PathManager.getJarPathForClass(Flow.class);
|
||||
if (annotationsRoot == null) return Collections.emptyList();
|
||||
return Arrays.asList(annotationsRoot, FileUtil.toSystemIndependentName(new File(new File(annotationsRoot).getParentFile(),
|
||||
moduleName).getAbsolutePath()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ExternalClassResolveResult resolveClass(@NotNull String shortClassName, @NotNull ThreeState isAnnotation, @NotNull Module contextModule) {
|
||||
|
||||
+10
-4
@@ -104,6 +104,12 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
|
||||
public static PsiExpression getInitializerExpression(PsiLocalVariable var,
|
||||
PsiAssignmentExpression assignment) {
|
||||
return getInitializerExpression(var.getInitializer(),
|
||||
assignment);
|
||||
}
|
||||
|
||||
public static PsiExpression getInitializerExpression(PsiExpression initializer,
|
||||
PsiAssignmentExpression assignment) {
|
||||
PsiExpression initializerExpression;
|
||||
final IElementType originalOpSign = assignment.getOperationTokenType();
|
||||
final PsiExpression rExpression = assignment.getRExpression();
|
||||
@@ -111,7 +117,7 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
initializerExpression = rExpression;
|
||||
}
|
||||
else {
|
||||
if (var.getInitializer() == null) return null;
|
||||
if (initializer == null) return null;
|
||||
String opSign = null;
|
||||
if (originalOpSign == JavaTokenType.ANDEQ) {
|
||||
opSign = "&";
|
||||
@@ -148,8 +154,8 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
}
|
||||
|
||||
try {
|
||||
final Project project = var.getProject();
|
||||
String initializerText = var.getInitializer().getText() + opSign;
|
||||
final Project project = assignment.getProject();
|
||||
String initializerText = initializer.getText() + opSign;
|
||||
final String rightText = rExpression.getText();
|
||||
if (ParenthesesUtils.areParenthesesNeeded(assignment.getOperationSign(), rExpression)) {
|
||||
initializerText += "(" + rightText + ")";
|
||||
@@ -157,7 +163,7 @@ public class DeclarationJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
else {
|
||||
initializerText += rightText;
|
||||
}
|
||||
initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, var);
|
||||
initializerExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(initializerText, assignment);
|
||||
initializerExpression = (PsiExpression)CodeStyleManager.getInstance(project).reformat(initializerExpression);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
|
||||
+2
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -24,8 +24,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author Danila Ponomarenko
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -36,11 +34,7 @@ public abstract class BaseColorIntentionAction extends PsiElementBaseIntentionAc
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
if (!psiElement().inside(psiElement(PsiNewExpression.class)).accepts(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false);
|
||||
final PsiNewExpression expression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class, false, PsiMember.class, PsiCodeBlock.class);
|
||||
return expression != null
|
||||
&& isJavaAwtColor(expression.getClassOrAnonymousClassReference())
|
||||
&& isValueArguments(expression.getArgumentList());
|
||||
|
||||
@@ -467,8 +467,6 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
private void generateTypeParametersSection(final StringBuilder buffer, final PsiClass aClass) {
|
||||
final PsiDocComment docComment = aClass.getDocComment();
|
||||
if (docComment == null) return;
|
||||
final LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>> result =
|
||||
new LinkedList<Pair<PsiDocTag, InheritDocProvider<PsiDocTag>>>();
|
||||
final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
|
||||
@@ -693,11 +691,9 @@ public class JavaDocInfoGenerator {
|
||||
try {
|
||||
final Document document = JDOMUtil.loadDocument(new ByteArrayInputStream(htmlText.getBytes(CharsetToolkit.UTF8_CHARSET)));
|
||||
final Element rootTag = document.getRootElement();
|
||||
if (rootTag != null) {
|
||||
final Element subTag = rootTag.getChild("body");
|
||||
if (subTag != null) {
|
||||
htmlText = subTag.getValue();
|
||||
}
|
||||
final Element subTag = rootTag.getChild("body");
|
||||
if (subTag != null) {
|
||||
htmlText = subTag.getValue();
|
||||
}
|
||||
}
|
||||
catch (JDOMException ignore) {}
|
||||
@@ -1107,6 +1103,7 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
private PsiDocComment loadSyntheticDocComment(final PsiMethod method, final String resourceName) {
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
final InputStream commentStream = JavaDocInfoGenerator.class.getResourceAsStream(resourceName);
|
||||
if (commentStream == null) {
|
||||
return null;
|
||||
@@ -1134,7 +1131,9 @@ public class JavaDocInfoGenerator {
|
||||
}
|
||||
|
||||
String s = buffer.toString();
|
||||
s = StringUtil.replace(s, "<ClassName>", method.getContainingClass().getName());
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
assert containingClass != null;
|
||||
s = StringUtil.replace(s, "<ClassName>", containingClass.getName());
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
try {
|
||||
return elementFactory.createDocCommentFromText(s);
|
||||
@@ -1298,6 +1297,7 @@ public class JavaDocInfoGenerator {
|
||||
return "";
|
||||
}
|
||||
|
||||
//noinspection ReplaceAllDot
|
||||
return "../" + ourNotDot.matcher(qName).replaceAll("").replaceAll(".", "../");
|
||||
}
|
||||
|
||||
@@ -1415,6 +1415,9 @@ public class JavaDocInfoGenerator {
|
||||
if (myElement instanceof PsiField) valueField = (PsiField) myElement;
|
||||
}
|
||||
else {
|
||||
if (text.indexOf('#') == -1) {
|
||||
text = "#" + text;
|
||||
}
|
||||
PsiElement target = JavaDocUtil.findReferenceTarget(PsiManager.getInstance(myProject), text, myElement);
|
||||
if (target instanceof PsiField) {
|
||||
valueField = (PsiField) target;
|
||||
@@ -2012,7 +2015,7 @@ public class JavaDocInfoGenerator {
|
||||
buffer.append(separator);
|
||||
length += 3;
|
||||
}
|
||||
length += generateType(buffer, psiType, context, generateLink, useShortNames);
|
||||
length += generateType(buffer, psiType, context, true, useShortNames);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.template;
|
||||
|
||||
import com.intellij.codeInsight.completion.JavaCompletionData;
|
||||
import com.intellij.codeInsight.completion.JavaKeywordCompletion;
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.ide.highlighter.JavaFileHighlighter;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.StandardPatterns.instanceOf;
|
||||
|
||||
public abstract class JavaCodeContextType extends TemplateContextType {
|
||||
|
||||
@@ -136,7 +137,7 @@ public abstract class JavaCodeContextType extends TemplateContextType {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (JavaCompletionData.isInsideParameterList(element)) {
|
||||
if (JavaKeywordCompletion.isInsideParameterList(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ public abstract class JavaCodeContextType extends TemplateContextType {
|
||||
|
||||
private static boolean isAfterExpression(PsiElement element) {
|
||||
ProcessingContext context = new ProcessingContext();
|
||||
if (psiElement().inside(PsiExpression.class).afterLeaf(psiElement().inside(psiElement(PsiExpression.class).save("prevExpr"))).accepts(element, context)) {
|
||||
if (psiElement().isOrParent(instanceOf(PsiExpression.class)).afterLeaf(psiElement().isOrParent(psiElement(PsiExpression.class).save("prevExpr"))).accepts(element, context)) {
|
||||
PsiExpression prevExpr = (PsiExpression)context.get("prevExpr");
|
||||
if (prevExpr.getTextRange().getEndOffset() <= element.getTextRange().getStartOffset()) {
|
||||
return true;
|
||||
@@ -167,7 +168,7 @@ public abstract class JavaCodeContextType extends TemplateContextType {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JavaCompletionData.isSuitableForClass(element) || JavaCompletionData.isInsideParameterList(element);
|
||||
return JavaKeywordCompletion.isSuitableForClass(element) || JavaKeywordCompletion.isInsideParameterList(element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-64
@@ -16,25 +16,18 @@
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInspection.ui.ListTable;
|
||||
import com.intellij.codeInspection.ui.ListWrappingTableModel;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.ui.UiUtils;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -45,56 +38,12 @@ import java.util.List;
|
||||
public class CollectionAddAllCanBeReplacedWithConstructorInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
private final static Logger LOG = Logger.getInstance(CollectionAddAllCanBeReplacedWithConstructorInspection.class);
|
||||
|
||||
private final List<String> myCollectionClassesToCheck = resetDefault(new ArrayList<String>());
|
||||
|
||||
@Override
|
||||
public void readSettings(@NotNull Element node) throws InvalidDataException {
|
||||
resetDefault(myCollectionClassesToCheck);
|
||||
for (Element element : node.getChildren()) {
|
||||
final String classFQN = element.getAttributeValue("name");
|
||||
if (element.getAttribute("delete") == null) {
|
||||
myCollectionClassesToCheck.add(classFQN);
|
||||
}
|
||||
else {
|
||||
myCollectionClassesToCheck.remove(classFQN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSettings(@NotNull Element node) throws WriteExternalException {
|
||||
List<String> defaultClasses = resetDefault(new ArrayList<String>());
|
||||
for (String aClass : myCollectionClassesToCheck) {
|
||||
defaultClasses.remove(aClass);
|
||||
}
|
||||
for (String aClass : defaultClasses) {
|
||||
node.addContent(new Element("cls").setAttribute("name", aClass).setAttribute("delete", "true"));
|
||||
}
|
||||
defaultClasses = resetDefault(new ArrayList<String>());
|
||||
for (String aClass : myCollectionClassesToCheck) {
|
||||
if (!defaultClasses.contains(aClass)) {
|
||||
node.addContent(new Element("cls").setAttribute("name", aClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JComponent createOptionsPanel() {
|
||||
final String title = QuickFixBundle.message("collection.addall.can.be.replaced.with.constructor.fix.options.title");
|
||||
final ListTable table = new ListTable(new ListWrappingTableModel(myCollectionClassesToCheck, title));
|
||||
return UiUtils.createAddRemoveTreeClassChooserPanel(table, title, CommonClassNames.JAVA_UTIL_COLLECTION);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder,
|
||||
boolean isOnTheFly,
|
||||
@NotNull LocalInspectionToolSession session) {
|
||||
if (myCollectionClassesToCheck.isEmpty()) {
|
||||
return PsiElementVisitor.EMPTY_VISITOR;
|
||||
}
|
||||
return new JavaRecursiveElementWalkingVisitor() {
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
final String methodName = expression.getMethodExpression().getReferenceName();
|
||||
@@ -147,7 +96,7 @@ public class CollectionAddAllCanBeReplacedWithConstructorInspection extends Base
|
||||
};
|
||||
}
|
||||
|
||||
private boolean checkLocalVariableAssignmentOrInitializer(PsiExpression initializer) {
|
||||
private static boolean checkLocalVariableAssignmentOrInitializer(PsiExpression initializer) {
|
||||
if (!(initializer instanceof PsiNewExpression)) {
|
||||
return false;
|
||||
}
|
||||
@@ -157,14 +106,31 @@ public class CollectionAddAllCanBeReplacedWithConstructorInspection extends Base
|
||||
return false;
|
||||
}
|
||||
final PsiClass initializerClass = (PsiClass)classReference.resolve();
|
||||
if (initializerClass == null || !myCollectionClassesToCheck.contains(initializerClass.getQualifiedName())) {
|
||||
if (initializerClass == null || !hasProperConstructor(initializerClass)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpressionList argumentList = newExpression.getArgumentList();
|
||||
return argumentList != null && argumentList.getExpressions().length == 0;
|
||||
}
|
||||
|
||||
private Pair<Boolean, PsiNewExpression> isProperAssignmentStatementFound(PsiLocalVariable localVariable, PsiMethodCallExpression addAllExpression) {
|
||||
private static boolean hasProperConstructor(PsiClass psiClass) {
|
||||
for (PsiMethod psiMethod : psiClass.getConstructors()) {
|
||||
PsiParameterList parameterList = psiMethod.getParameterList();
|
||||
if(parameterList.getParametersCount() == 1) {
|
||||
PsiParameter parameter = parameterList.getParameters()[0];
|
||||
PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
PsiType type = typeElement.getType();
|
||||
if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_COLLECTION)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Pair<Boolean, PsiNewExpression> isProperAssignmentStatementFound(PsiLocalVariable localVariable, PsiMethodCallExpression addAllExpression) {
|
||||
PsiStatement currentStatement = PsiTreeUtil.getParentOfType(addAllExpression, PsiStatement.class);
|
||||
final PsiStatement localVariableDefinitionStatement = PsiTreeUtil.getParentOfType(localVariable, PsiStatement.class);
|
||||
while (currentStatement != null) {
|
||||
@@ -221,15 +187,6 @@ public class CollectionAddAllCanBeReplacedWithConstructorInspection extends Base
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> resetDefault(final List<String> classes) {
|
||||
classes.clear();
|
||||
classes.add(CommonClassNames.JAVA_UTIL_ARRAY_LIST);
|
||||
classes.add(CommonClassNames.JAVA_UTIL_HASH_SET);
|
||||
classes.add("java.util.Vector");
|
||||
classes.add("java.util.concurrent.CopyOnWriteArrayList");
|
||||
return classes;
|
||||
}
|
||||
|
||||
private static List<PsiElement> extractReferencedElementsFromParameter(PsiMethodCallExpression expression) {
|
||||
final PsiExpression psiExpression = expression.getArgumentList().getExpressions()[0];
|
||||
final Collection<PsiReferenceExpression> references =
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.editorActions.DeclarationJoinLinesHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -38,7 +40,12 @@ public class RemoveAssignmentFix extends RemoveInitializerFix {
|
||||
parent = element;
|
||||
}
|
||||
if (!(parent instanceof PsiAssignmentExpression)) return;
|
||||
final PsiExpression rExpression = ((PsiAssignmentExpression)parent).getRExpression();
|
||||
final IElementType operationSign = ((PsiAssignmentExpression)parent).getOperationTokenType();
|
||||
PsiExpression rExpression = ((PsiAssignmentExpression)parent).getRExpression();
|
||||
if (JavaTokenType.EQ != operationSign && rExpression != null ) {
|
||||
rExpression = DeclarationJoinLinesHandler.getInitializerExpression(((PsiAssignmentExpression)parent).getLExpression(),
|
||||
(PsiAssignmentExpression)parent);
|
||||
}
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if ((gParent instanceof PsiExpression || gParent instanceof PsiExpressionList || gParent instanceof PsiReturnStatement) && rExpression != null) {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(gParent.getContainingFile())) return;
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectUtil;
|
||||
import com.intellij.openapi.roots.DependencyScope;
|
||||
@@ -271,7 +272,7 @@ public class InferNullityAnnotationsAction extends BaseAnalysisAction {
|
||||
}
|
||||
|
||||
private void restartAnalysis(final Project project, final AnalysisScope scope) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
DumbService.getInstance(project).smartInvokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
analyze(project, scope);
|
||||
|
||||
@@ -157,7 +157,7 @@ public class NullityInferrer {
|
||||
}
|
||||
}
|
||||
|
||||
static void nothingFoundMessage(final Project project) {
|
||||
public static void nothingFoundMessage(final Project project) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ public class MagicCompletionContributor extends CompletionContributor {
|
||||
PsiElement pos = parameters.getPosition();
|
||||
MagicConstantInspection.AllowedValues allowedValues = null;
|
||||
|
||||
if (JavaCompletionData.AFTER_DOT.accepts(pos)) {
|
||||
if (JavaKeywordCompletion.AFTER_DOT.accepts(pos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ class JrtHandler extends ArchiveHandler {
|
||||
|
||||
private static final URI ROOT_URI = URI.create("jrt:/");
|
||||
private static final Map<String, Object> EMPTY_ENV = Collections.emptyMap();
|
||||
private static final String PREFIX = "/modules";
|
||||
|
||||
private static class JrtEntryInfo extends EntryInfo {
|
||||
private final String myModule;
|
||||
@@ -78,10 +79,10 @@ class JrtHandler extends ArchiveHandler {
|
||||
map.put("", createRootEntry());
|
||||
|
||||
//FileSystem fs = (FileSystem)getFileSystem();
|
||||
//Path root = fs.getPath("/");
|
||||
//Path root = fs.getPath("/modules");
|
||||
//Files.walk(root).forEachOrdered((p) -> {
|
||||
Object fs = getFileSystem();
|
||||
Object root = call(getPath, fs, "/", ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
Object root = call(getPath, fs, PREFIX, ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
Object stream = call(walk, root, Array.newInstance(cls("java.nio.file.FileVisitOption"), 0));
|
||||
call(forEachOrdered, stream, Proxy.newProxyInstance(
|
||||
getClass().getClassLoader(), new Class[]{cls("java.util.function.Consumer")}, new InvocationHandler() {
|
||||
@@ -90,7 +91,7 @@ class JrtHandler extends ArchiveHandler {
|
||||
//String path = p.toString();
|
||||
String path = args[0].toString();
|
||||
|
||||
int p = path.indexOf('/', 1);
|
||||
int p = path.indexOf('/', PREFIX.length() + 1);
|
||||
if (p < 0) return null;
|
||||
String module = path.substring(1, p);
|
||||
path = path.substring(p + 1);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.formatting.alignment.AlignmentStrategy;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiSyntheticClass;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
@@ -122,7 +123,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
|
||||
if (child.getElementType() == JavaElementType.SWITCH_LABEL_STATEMENT) {
|
||||
child = processCaseAndStatementAfter(result, child, childAlignment, childWrap, indent);
|
||||
}
|
||||
else if (myNode.getElementType() == JavaElementType.CLASS && child.getElementType() == JavaTokenType.LBRACE) {
|
||||
else if (myNode.getPsi() instanceof PsiClass && child.getElementType() == JavaTokenType.LBRACE) {
|
||||
child = composeCodeBlock(result, child, getCodeBlockExternalIndent(), myChildrenIndent, null);
|
||||
}
|
||||
else if (myNode.getElementType() == JavaElementType.CODE_BLOCK && child.getElementType() == JavaTokenType.LBRACE
|
||||
|
||||
+6
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiReferenceContributor;
|
||||
import com.intellij.psi.PsiReferenceRegistrar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiExpression;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiLiteral;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
@@ -32,11 +31,11 @@ import static com.intellij.psi.CommonClassNames.JAVA_LANG_CLASS;
|
||||
*/
|
||||
public class JavaReflectionReferenceContributor extends PsiReferenceContributor {
|
||||
public static final PsiJavaElementPattern.Capture<PsiLiteral> PATTERN =
|
||||
psiLiteral().inside(psiExpression().methodCall(psiMethod().withName(string().oneOf("getDeclaredField",
|
||||
"getField",
|
||||
"getMethod",
|
||||
"getDeclaredMethod"))
|
||||
.definedInClass(JAVA_LANG_CLASS)));
|
||||
psiLiteral().methodCallParameter(psiMethod().withName(string().oneOf("getDeclaredField",
|
||||
"getField",
|
||||
"getMethod",
|
||||
"getDeclaredMethod"))
|
||||
.definedInClass(JAVA_LANG_CLASS));
|
||||
|
||||
@Override
|
||||
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
|
||||
|
||||
+1
-3
@@ -23,8 +23,6 @@ import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
|
||||
import com.intellij.codeInsight.generation.GenerateMembersUtil;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNullableNotNullAnnotationFix;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.codeInspection.dataFlow.*;
|
||||
@@ -1722,7 +1720,7 @@ public class ExtractMethodProcessor implements MatchProvider {
|
||||
|
||||
if (myExtractedMethod != null) {
|
||||
final ExtractMethodSignatureSuggester suggester = new ExtractMethodSignatureSuggester(myProject, myExtractedMethod, myMethodCall, myVariableDatum);
|
||||
duplicates = suggester.getDuplicates(myExtractedMethod, myMethodCall);
|
||||
duplicates = suggester.getDuplicates(myExtractedMethod, myMethodCall, myInputVariables.getFolding());
|
||||
if (duplicates != null && !duplicates.isEmpty()) {
|
||||
myDuplicates = duplicates;
|
||||
myExtractedMethod = suggester.getExtractedMethod();
|
||||
|
||||
+13
-12
@@ -89,8 +89,8 @@ public class ExtractMethodSignatureSuggester {
|
||||
myVariableData = variableDatum;
|
||||
}
|
||||
|
||||
public List<Match> getDuplicates(final PsiMethod method, final PsiMethodCallExpression methodCall) {
|
||||
final List<Match> duplicates = findDuplicatesSignature(method);
|
||||
public List<Match> getDuplicates(final PsiMethod method, final PsiMethodCallExpression methodCall, ParametersFolder folder) {
|
||||
final List<Match> duplicates = findDuplicatesSignature(method, folder);
|
||||
if (duplicates != null && !duplicates.isEmpty()) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
new PreviewDialog(method, myExtractedMethod, methodCall, myMethodCall, duplicates.size()).showAndGet()) {
|
||||
@@ -127,7 +127,7 @@ public class ExtractMethodSignatureSuggester {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<Match> findDuplicatesSignature(final PsiMethod method) {
|
||||
public List<Match> findDuplicatesSignature(final PsiMethod method, ParametersFolder folder) {
|
||||
final List<PsiExpression> copies = new ArrayList<PsiExpression>();
|
||||
final InputVariables variables = detectTopLevelExpressionsToReplaceWithParameters(copies);
|
||||
if (variables == null) {
|
||||
@@ -148,7 +148,7 @@ public class ExtractMethodSignatureSuggester {
|
||||
List<Match> duplicates = finder.findDuplicates(method.getContainingClass());
|
||||
|
||||
if (duplicates != null && !duplicates.isEmpty()) {
|
||||
restoreRenamedParams(copies);
|
||||
restoreRenamedParams(copies, folder);
|
||||
if (!myMethodCall.isValid()) {
|
||||
return null;
|
||||
}
|
||||
@@ -255,17 +255,18 @@ public class ExtractMethodSignatureSuggester {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void restoreRenamedParams(List<PsiExpression> copies) {
|
||||
final Map<String, PsiVariable> renameMap = new HashMap<String, PsiVariable>();
|
||||
private void restoreRenamedParams(List<PsiExpression> copies, ParametersFolder folder) {
|
||||
final Map<String, String> renameMap = new HashMap<String, String>();
|
||||
for (VariableData data : myVariableData) {
|
||||
if (!data.name.equals(data.variable.getName())) {
|
||||
renameMap.put(data.name, data.variable);
|
||||
final String replacement = folder.getGeneratedCallArgument(data);
|
||||
if (!data.name.equals(replacement)) {
|
||||
renameMap.put(data.name, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (!renameMap.isEmpty()) {
|
||||
for (PsiExpression currentExpression : copies) {
|
||||
final Map<PsiReferenceExpression, PsiVariable> params = new HashMap<PsiReferenceExpression, PsiVariable>();
|
||||
final Map<PsiReferenceExpression, String> params = new HashMap<PsiReferenceExpression, String>();
|
||||
currentExpression.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
@@ -273,7 +274,7 @@ public class ExtractMethodSignatureSuggester {
|
||||
final PsiElement resolve = expression.resolve();
|
||||
if (resolve instanceof PsiParameter && myExtractedMethod.equals(((PsiParameter)resolve).getDeclarationScope())) {
|
||||
final String name = ((PsiParameter)resolve).getName();
|
||||
final PsiVariable variable = renameMap.get(name);
|
||||
final String variable = renameMap.get(name);
|
||||
if (renameMap.containsKey(name)) {
|
||||
params.put(expression, variable);
|
||||
}
|
||||
@@ -281,8 +282,8 @@ public class ExtractMethodSignatureSuggester {
|
||||
}
|
||||
});
|
||||
for (PsiReferenceExpression expression : params.keySet()) {
|
||||
final PsiVariable var = params.get(expression);
|
||||
expression.replace(myElementFactory.createExpressionFromText(var.getName(), expression));
|
||||
final String var = params.get(expression);
|
||||
expression.replace(myElementFactory.createExpressionFromText(var, expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,39 +59,38 @@ public class ExtractClassHandler implements ElementsHandler {
|
||||
containingClass = (PsiClass)selectedMember;
|
||||
}
|
||||
|
||||
if (containingClass == null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.caret.should.be.positioned.within.a.class.to.be.refactored"),
|
||||
final String cannotRefactorMessage = getCannotRefactorMessage(containingClass);
|
||||
if (cannotRefactorMessage != null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor,
|
||||
RefactorJBundle.message("cannot.perform.the.refactoring") + cannotRefactorMessage,
|
||||
null, getHelpID());
|
||||
return;
|
||||
}
|
||||
if (containingClass.isInterface()) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.selected.class.is.an.interface"), null,
|
||||
getHelpID());
|
||||
return;
|
||||
}
|
||||
if (containingClass.isEnum()) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.selected.class.is.an.enumeration"), null,
|
||||
getHelpID());
|
||||
return;
|
||||
}
|
||||
if (containingClass.isAnnotationType()) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.selected.class.is.an.annotation.type"), null,
|
||||
getHelpID());
|
||||
return;
|
||||
}
|
||||
if (classIsInner(containingClass) && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.refactoring.is.not.supported.on.non.static.inner.classes"),
|
||||
null, getHelpID());
|
||||
return;
|
||||
}
|
||||
if (classIsTrivial(containingClass)) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactorJBundle.message("cannot.perform.the.refactoring") + RefactorJBundle.message("the.selected.class.has.no.members.to.extract"), null,
|
||||
getHelpID());
|
||||
return;
|
||||
}
|
||||
new ExtractClassDialog(containingClass, selectedMember).show();
|
||||
}
|
||||
|
||||
private static String getCannotRefactorMessage(PsiClass containingClass) {
|
||||
if (containingClass == null) {
|
||||
return RefactorJBundle.message("the.caret.should.be.positioned.within.a.class.to.be.refactored");
|
||||
}
|
||||
if (containingClass.isInterface()) {
|
||||
return RefactorJBundle.message("the.selected.class.is.an.interface");
|
||||
}
|
||||
if (containingClass.isEnum()) {
|
||||
return RefactorJBundle.message("the.selected.class.is.an.enumeration");
|
||||
}
|
||||
if (containingClass.isAnnotationType()) {
|
||||
return RefactorJBundle.message("the.selected.class.is.an.annotation.type");
|
||||
}
|
||||
if (classIsInner(containingClass) && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return RefactorJBundle.message("the.refactoring.is.not.supported.on.non.static.inner.classes");
|
||||
}
|
||||
if (classIsTrivial(containingClass)) {
|
||||
return RefactorJBundle.message("the.selected.class.has.no.members.to.extract");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean classIsInner(PsiClass aClass) {
|
||||
return PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true) != null;
|
||||
}
|
||||
|
||||
+24
-5
@@ -19,8 +19,10 @@ import com.intellij.codeInsight.generation.GenerateMembersUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.psi.MutationUtils;
|
||||
import com.intellij.refactoring.util.FixableUsageInfo;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
@@ -51,13 +53,19 @@ public class ReplaceStaticVariableAccess extends FixableUsageInfo {
|
||||
}
|
||||
|
||||
private boolean alreadyMigratedToEnum() {
|
||||
final PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(expression, PsiMethodCallExpression.class);
|
||||
final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(expression, PsiCallExpression.class);
|
||||
if (callExpression != null) {
|
||||
final PsiElement resolved = callExpression.getMethodExpression().resolve();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
final PsiParameter[] parameters = ((PsiMethod)resolved).getParameterList().getParameters();
|
||||
final PsiMethod resolvedMethod = callExpression.resolveMethod();
|
||||
if (resolvedMethod != null) {
|
||||
final PsiParameter[] parameters = resolvedMethod.getParameterList().getParameters();
|
||||
final PsiExpression[] args = callExpression.getArgumentList().getExpressions();
|
||||
final int idx = ArrayUtilRt.find(args, expression);
|
||||
int idx = -1;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (PsiTreeUtil.isAncestor(args[i], expression, false)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx != -1 && parameters[idx].getType().equalsToText(delegateClass)) {
|
||||
return true;
|
||||
}
|
||||
@@ -89,6 +97,17 @@ public class ReplaceStaticVariableAccess extends FixableUsageInfo {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiBinaryExpression binaryExpression = PsiTreeUtil.getParentOfType(expression, PsiBinaryExpression.class);
|
||||
if (binaryExpression != null && binaryExpression.getOperationTokenType() == JavaTokenType.EQEQ) {
|
||||
final PsiExpression[] operands = binaryExpression.getOperands();
|
||||
final int index = ArrayUtil.find(operands, expression);
|
||||
if (index >= 0) {
|
||||
final PsiType type = operands[index].getType();
|
||||
return type != null && type.equalsToText(delegateClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
PsiSubstitutor callSubstitutor = getCallSubstitutor(methodCall);
|
||||
BlockData blockData = prepareBlock(ref, callSubstitutor, methodCall.getArgumentList(), tailCall);
|
||||
solveVariableNameConflicts(blockData.block, ref);
|
||||
InlineUtil.solveVariableNameConflicts(blockData.block, ref, myMethodCopy.getBody());
|
||||
if (callSubstitutor != PsiSubstitutor.EMPTY) {
|
||||
substituteMethodTypeParams(blockData.block, callSubstitutor);
|
||||
}
|
||||
@@ -851,31 +851,6 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
return new BlockData(block, thisVar, parmVars, resultVar);
|
||||
}
|
||||
|
||||
private void solveVariableNameConflicts(PsiElement scope, final PsiElement placeToInsert) throws IncorrectOperationException {
|
||||
if (scope instanceof PsiVariable) {
|
||||
PsiVariable var = (PsiVariable)scope;
|
||||
String name = var.getName();
|
||||
String oldName = name;
|
||||
while (true) {
|
||||
String newName = myJavaCodeStyle.suggestUniqueVariableName(name, placeToInsert, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
newName = myJavaCodeStyle.suggestUniqueVariableName(name, var, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
}
|
||||
if (!name.equals(oldName)) {
|
||||
RefactoringUtil.renameVariableReferences(var, name, new LocalSearchScope(myMethodCopy.getBody()), true);
|
||||
var.getNameIdentifier().replace(myFactory.createIdentifier(name));
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement[] children = scope.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
solveVariableNameConflicts(child, placeToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
private void addParmAndThisVarInitializers(BlockData blockData, PsiMethodCallExpression methodCall) throws IncorrectOperationException {
|
||||
PsiExpression[] args = methodCall.getArgumentList().getExpressions();
|
||||
if (blockData.parmVars.length > 0) {
|
||||
|
||||
+1
-2
@@ -128,8 +128,7 @@ public class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroduce
|
||||
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
final PsiVariable variable = getLocalVariable();
|
||||
return variable == null ? myMethod : PsiTreeUtil.getParentOfType(variable, PsiMethod.class);
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -502,7 +502,7 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
|
||||
public boolean process(final PsiReference reference) {
|
||||
final PsiElement element = reference.getElement();
|
||||
|
||||
if (!isInside(element, allElementsToDelete)) {
|
||||
if (!isInside(element, allElementsToDelete) && element instanceof PsiJavaCodeReferenceElement) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiReferenceList) {
|
||||
final PsiElement pparent = parent.getParent();
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.RedundantCastUtil;
|
||||
@@ -52,6 +54,7 @@ public class InlineUtil {
|
||||
boolean insertCastWhenUnchecked = ref.getParent() instanceof PsiForeachStatement;
|
||||
final PsiType varType = variable.getType();
|
||||
initializer = RefactoringUtil.convertInitializerToNormalExpression(initializer, varType);
|
||||
solveVariableNameConflicts(initializer, ref, initializer);
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(initializer, false);
|
||||
PsiExpression expr = (PsiExpression)replaceDiamondWithInferredTypesIfNeeded(initializer, ref);
|
||||
@@ -400,6 +403,34 @@ public class InlineUtil {
|
||||
return ref != initializer ? ref.replace(initializer) : initializer;
|
||||
}
|
||||
|
||||
public static void solveVariableNameConflicts(final PsiElement scope,
|
||||
final PsiElement placeToInsert,
|
||||
final PsiElement renameScope) throws IncorrectOperationException {
|
||||
if (scope instanceof PsiVariable) {
|
||||
PsiVariable var = (PsiVariable)scope;
|
||||
String name = var.getName();
|
||||
String oldName = name;
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(scope.getProject());
|
||||
while (true) {
|
||||
String newName = codeStyleManager.suggestUniqueVariableName(name, placeToInsert, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
newName = codeStyleManager.suggestUniqueVariableName(name, var, true);
|
||||
if (newName.equals(name)) break;
|
||||
name = newName;
|
||||
}
|
||||
if (!name.equals(oldName)) {
|
||||
RefactoringUtil.renameVariableReferences(var, name, new LocalSearchScope(renameScope), true);
|
||||
var.getNameIdentifier().replace(JavaPsiFacade.getElementFactory(scope.getProject()).createIdentifier(name));
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement[] children = scope.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
solveVariableNameConflicts(child, placeToInsert, renameScope);
|
||||
}
|
||||
}
|
||||
|
||||
public enum TailCallType {
|
||||
None, Simple, Return
|
||||
}
|
||||
|
||||
@@ -501,7 +501,12 @@ public class AnnotationUtil {
|
||||
}
|
||||
|
||||
public static boolean isInsideAnnotation(PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PsiNameValuePair.class, PsiArrayInitializerMemberValue.class) != null;
|
||||
for (int level = 0; level<4; level++) {
|
||||
if (element instanceof PsiNameValuePair) return true;
|
||||
element = element.getParent();
|
||||
if (element == null) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isInferredAnnotation(@NotNull PsiAnnotation annotation) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -48,9 +48,21 @@ public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElem
|
||||
PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
|
||||
PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
|
||||
}
|
||||
public Self annotationParam(@NotNull ElementPattern<PsiAnnotation> annotation) {
|
||||
return withParent(
|
||||
PsiJavaPatterns.psiNameValuePair().withParent(
|
||||
PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
|
||||
annotation)));
|
||||
}
|
||||
|
||||
public Self annotationParam(String parameterName, @NotNull ElementPattern<PsiAnnotation> annotation) {
|
||||
return withParent(
|
||||
PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
|
||||
PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(annotation)));
|
||||
}
|
||||
|
||||
public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
|
||||
return inside(true,
|
||||
return isOrParentAtMost(3, // can be array initializer
|
||||
PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
|
||||
PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
|
||||
PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
|
||||
@@ -60,6 +72,10 @@ public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElem
|
||||
return insideAnnotationParam(annotationQualifiedName, VALUE);
|
||||
}
|
||||
|
||||
public Self insideAnnotationParam(@NotNull String annotationQualifiedName) {
|
||||
return insideAnnotationParam(StandardPatterns.string().equalTo(annotationQualifiedName));
|
||||
}
|
||||
|
||||
public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
|
||||
return nameIdentifierOf(StandardPatterns.instanceOf(aClass));
|
||||
}
|
||||
@@ -106,6 +122,30 @@ public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElem
|
||||
});
|
||||
}
|
||||
|
||||
public Self methodCallParameter(@NotNull final ElementPattern<? extends PsiMethod> methodPattern) {
|
||||
return with(new PatternCondition<T>("methodCallParameter") {
|
||||
@Override
|
||||
public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
|
||||
final PsiElement parent = literal.getParent();
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
|
||||
|
||||
final PsiElement element = psiExpressionList.getParent();
|
||||
if (element instanceof PsiMethodCallExpression) {
|
||||
final JavaResolveResult[] results = ((PsiMethodCallExpression)element).getMethodExpression().multiResolve(false);
|
||||
for (JavaResolveResult result : results) {
|
||||
final PsiElement psiElement = result.getElement();
|
||||
if (methodPattern.accepts(psiElement, context)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Self constructorParameter(final int index, final String... fqns) {
|
||||
return with(new PatternCondition<T>("methodCallParameter") {
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -143,16 +143,18 @@ public class PsiPrimitiveType extends PsiType.Stub {
|
||||
*/
|
||||
@Nullable
|
||||
public PsiClassType getBoxedType(PsiElement context) {
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(context);
|
||||
PsiFile file = context.getContainingFile();
|
||||
LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;
|
||||
|
||||
String boxedQName = getBoxedTypeName();
|
||||
//[ven]previous call returns null for NULL, VOID
|
||||
if (boxedQName == null) return null;
|
||||
PsiClass aClass = JavaPsiFacade.getInstance(context.getProject()).findClass(boxedQName, context.getResolveScope());
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
|
||||
PsiClass aClass = facade.findClass(boxedQName, context.getResolveScope());
|
||||
if (aClass == null) return null;
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = facade.getElementFactory();
|
||||
return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel, getAnnotations());
|
||||
}
|
||||
|
||||
|
||||
@@ -1247,11 +1247,11 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PsiReturnStatement[] findReturnStatements(PsiMethod method) {
|
||||
public static PsiReturnStatement[] findReturnStatements(@NotNull PsiMethod method) {
|
||||
return findReturnStatements(method.getBody());
|
||||
}
|
||||
|
||||
public static PsiReturnStatement[] findReturnStatements(PsiCodeBlock body) {
|
||||
public static PsiReturnStatement[] findReturnStatements(@Nullable PsiCodeBlock body) {
|
||||
ArrayList<PsiReturnStatement> vector = new ArrayList<PsiReturnStatement>();
|
||||
if (body != null) {
|
||||
addReturnStatements(vector, body);
|
||||
|
||||
@@ -182,7 +182,7 @@ public class JavaLexer extends LexerBase {
|
||||
}
|
||||
catch (IOException e) { /* impossible */ }
|
||||
catch (Error e) {
|
||||
throw new IllegalArgumentException("Non-parsable text `" + myBuffer + "`");
|
||||
throw new IllegalArgumentException("Non-parsable text `" + myBuffer + "`", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -137,11 +137,11 @@ public class JavadocParser {
|
||||
else if (TAG_VALUES_SET.contains(tokenType)) {
|
||||
if (SEE_TAG.equals(tagName) && !isInline ||
|
||||
LINK_TAG.equals(tagName) && isInline) {
|
||||
parseSeeTagValue(builder);
|
||||
parseSeeTagValue(builder, false);
|
||||
}
|
||||
else {
|
||||
if (JavaParserUtil.getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_4) && LINK_PLAIN_TAG.equals(tagName) && isInline) {
|
||||
parseSeeTagValue(builder);
|
||||
parseSeeTagValue(builder, false);
|
||||
}
|
||||
else if (!isInline && (THROWS_TAG.equals(tagName) || EXCEPTION_TAG.equals(tagName))) {
|
||||
final PsiBuilder.Marker tagValue = builder.mark();
|
||||
@@ -154,7 +154,7 @@ public class JavadocParser {
|
||||
}
|
||||
else {
|
||||
if (JavaParserUtil.getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_5) && VALUE_TAG.equals(tagName) && isInline) {
|
||||
parseSeeTagValue(builder);
|
||||
parseSeeTagValue(builder, true);
|
||||
}
|
||||
else {
|
||||
parseSimpleTagValue(builder, false);
|
||||
@@ -167,7 +167,7 @@ public class JavadocParser {
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseSeeTagValue(@NotNull final PsiBuilder builder) {
|
||||
private static void parseSeeTagValue(@NotNull final PsiBuilder builder, boolean allowBareFieldReference) {
|
||||
final IElementType tokenType = getTokenType(builder);
|
||||
if (tokenType == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
|
||||
parseMethodRef(builder, builder.mark());
|
||||
@@ -180,6 +180,11 @@ public class JavadocParser {
|
||||
if (getTokenType(builder) == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
|
||||
parseMethodRef(builder, refStart);
|
||||
}
|
||||
else if (allowBareFieldReference) {
|
||||
refStart.rollbackTo();
|
||||
builder.remapCurrentToken(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
|
||||
parseMethodRef(builder, builder.mark());
|
||||
}
|
||||
else {
|
||||
refStart.drop();
|
||||
}
|
||||
@@ -192,8 +197,9 @@ public class JavadocParser {
|
||||
}
|
||||
|
||||
private static void parseMethodRef(@NotNull final PsiBuilder builder, @NotNull final PsiBuilder.Marker refStart) {
|
||||
builder.advanceLexer();
|
||||
|
||||
if (getTokenType(builder) == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
if (getTokenType(builder) != JavaDocTokenType.DOC_TAG_VALUE_TOKEN) {
|
||||
refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF);
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.compiled;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectCoreUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.PsiFileStub;
|
||||
@@ -43,6 +45,10 @@ public abstract class ClsRepositoryPsiElement<T extends StubElement> extends Cls
|
||||
|
||||
@Override
|
||||
public PsiManager getManager() {
|
||||
Project project = ProjectCoreUtil.theOnlyOpenProject();
|
||||
if (project != null) {
|
||||
return PsiManager.getInstance(project);
|
||||
}
|
||||
final PsiFile file = getContainingFile();
|
||||
if (file == null) throw new PsiInvalidElementAccessException(this);
|
||||
return file.getManager();
|
||||
|
||||
@@ -29,7 +29,7 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
private final String myText;
|
||||
private final String myClassName;
|
||||
private final PsiElement myContext;
|
||||
private final GlobalSearchScope myResolveScope;
|
||||
@NotNull private final GlobalSearchScope myResolveScope;
|
||||
private final PsiClass myRefClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
|
||||
@@ -50,14 +50,13 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
this (manager, text, className, null, resolveScope);
|
||||
}
|
||||
|
||||
public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull @NonNls String className, PsiSubstitutor substitutor, PsiElement context) {
|
||||
public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull @NonNls String className, PsiSubstitutor substitutor, @NotNull PsiElement context) {
|
||||
super(manager, JavaLanguage.INSTANCE);
|
||||
myText = text;
|
||||
myClassName = className;
|
||||
mySubstitutor = substitutor;
|
||||
myContext = context;
|
||||
|
||||
myResolveScope = null;
|
||||
myResolveScope = context.getResolveScope();
|
||||
myRefClass = null;
|
||||
}
|
||||
|
||||
@@ -69,8 +68,7 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
super(manager, JavaLanguage.INSTANCE);
|
||||
myText = text;
|
||||
myRefClass = refClass;
|
||||
|
||||
myResolveScope = null;
|
||||
myResolveScope = refClass.getResolveScope();
|
||||
myClassName = null;
|
||||
myContext = null;
|
||||
mySubstitutor = substitutor;
|
||||
@@ -179,11 +177,11 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
String name = getQualifiedName();
|
||||
if (name == null) return null;
|
||||
if (name == null) return "";
|
||||
PsiType[] types = getTypeParameters();
|
||||
if (types.length == 0) return name;
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(name);
|
||||
buf.append('<');
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
|
||||
@@ -268,6 +268,10 @@ public class PsiImmediateClassType extends PsiClassType.Stub {
|
||||
|
||||
@Override
|
||||
public boolean equalsToText(@NotNull String text) {
|
||||
String name = myClass.getName();
|
||||
if (name == null || !text.contains(name)) return false;
|
||||
if (text.equals(getCanonicalText(false))) return true;
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
|
||||
final PsiType patternType;
|
||||
try {
|
||||
|
||||
+6
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -155,8 +155,8 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
|
||||
@Nullable
|
||||
public PsiElement getNameElement() {
|
||||
final ASTNode sharp = findChildByType(DOC_TAG_VALUE_SHARP_TOKEN);
|
||||
return sharp != null ? SourceTreeToPsiMap.treeToPsiNotNull(sharp).getNextSibling() : null;
|
||||
final ASTNode name = findChildByType(DOC_TAG_VALUE_TOKEN);
|
||||
return name != null ? SourceTreeToPsiMap.treeToPsiNotNull(name) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -174,11 +174,9 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
|
||||
if (child.getNode().getElementType() == DOC_TYPE_HOLDER) {
|
||||
final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm method(paramType1, paramType2, ...) -> typeElement1, identifier2, ...
|
||||
if (typeStrings != null) {
|
||||
for (String type : typeStrings) {
|
||||
if (!type.isEmpty()) {
|
||||
types.add(type);
|
||||
}
|
||||
for (String type : typeStrings) {
|
||||
if (!type.isEmpty()) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-15
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.psi.scope.conflictResolvers;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
@@ -209,11 +208,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
for (CandidateInfo conflict : conflicts) {
|
||||
final PsiMethod method = ((MethodCandidateInfo)conflict).getElement();
|
||||
for (HierarchicalMethodSignature methodSignature : method.getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||
final PsiMethod superMethod = methodSignature.getMethod();
|
||||
final PsiClass aClass = superMethod.getContainingClass();
|
||||
if (aClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) {
|
||||
superMethods.add(superMethod);
|
||||
}
|
||||
superMethods.add(methodSignature.getMethod());
|
||||
}
|
||||
}
|
||||
nextConflict:
|
||||
@@ -594,19 +589,12 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
if (class1 != class2) {
|
||||
if (class2.isInheritor(class1, true) || class1.isInterface() && !class2.isInterface()) {
|
||||
if (MethodSignatureUtil.isSubsignature(method1.getSignature(getSubstitutor(info1, map)), method2.getSignature(getSubstitutor(info2, map)))) {
|
||||
if (isSubSignature(method1, method2, classSubstitutor1, classSubstitutor2, boxingHappened)) {
|
||||
return Specifics.SECOND;
|
||||
}
|
||||
else if (method1.hasModifierProperty(PsiModifier.STATIC) && method2.hasModifierProperty(PsiModifier.STATIC) && boxingHappened[0] == 0) {
|
||||
return Specifics.SECOND;
|
||||
}
|
||||
}
|
||||
else if (MethodSignatureUtil.areErasedParametersEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY)) &&
|
||||
MethodSignatureUtil.isSubsignature(method2.getSignature(getSubstitutor(info2, map)), method1.getSignature(getSubstitutor(info1, map)))) {
|
||||
return Specifics.FIRST;
|
||||
}
|
||||
else if (class1.isInheritor(class2, true) || class2.isInterface()) {
|
||||
if (method1.hasModifierProperty(PsiModifier.STATIC) && method2.hasModifierProperty(PsiModifier.STATIC) && boxingHappened[0] == 0) {
|
||||
if (isSubSignature(method2, method1, classSubstitutor2, classSubstitutor1, boxingHappened)) {
|
||||
return Specifics.FIRST;
|
||||
}
|
||||
}
|
||||
@@ -627,6 +615,16 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
return Specifics.NEITHER;
|
||||
}
|
||||
|
||||
private static boolean isSubSignature(PsiMethod method1,
|
||||
PsiMethod method2,
|
||||
PsiSubstitutor classSubstitutor1,
|
||||
PsiSubstitutor classSubstitutor2,
|
||||
int[] boxingHappened) {
|
||||
return MethodSignatureUtil.areErasedParametersEqual(method1.getSignature(PsiSubstitutor.EMPTY), method2.getSignature(PsiSubstitutor.EMPTY)) &&
|
||||
MethodSignatureUtil.isSubsignature(method1.getSignature(classSubstitutor1), method2.getSignature(classSubstitutor2)) ||
|
||||
method1.hasModifierProperty(PsiModifier.STATIC) && method2.hasModifierProperty(PsiModifier.STATIC) && boxingHappened[0] == 0;
|
||||
}
|
||||
|
||||
private boolean isApplicableTo(@NotNull PsiType[] types2AtSite,
|
||||
@NotNull PsiMethod method1,
|
||||
@NotNull LanguageLevel languageLevel,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -51,7 +52,7 @@ public class CanonicalTypes {
|
||||
private abstract static class AnnotatedType extends Type {
|
||||
protected final PsiAnnotation[] myAnnotations;
|
||||
|
||||
protected AnnotatedType(PsiAnnotation[] annotations) {
|
||||
protected AnnotatedType(@NotNull PsiAnnotation[] annotations) {
|
||||
myAnnotations = annotations;
|
||||
}
|
||||
}
|
||||
@@ -59,7 +60,7 @@ public class CanonicalTypes {
|
||||
private static class Primitive extends AnnotatedType {
|
||||
private final PsiPrimitiveType myType;
|
||||
|
||||
private Primitive(PsiPrimitiveType type) {
|
||||
private Primitive(@NotNull PsiPrimitiveType type) {
|
||||
super(type.getAnnotations());
|
||||
myType = type;
|
||||
}
|
||||
@@ -79,7 +80,7 @@ public class CanonicalTypes {
|
||||
private static class Array extends AnnotatedType {
|
||||
protected final Type myComponentType;
|
||||
|
||||
private Array(PsiType original, Type componentType) {
|
||||
private Array(@NotNull PsiType original, @NotNull Type componentType) {
|
||||
super(original.getAnnotations());
|
||||
myComponentType = componentType;
|
||||
}
|
||||
@@ -107,7 +108,7 @@ public class CanonicalTypes {
|
||||
}
|
||||
|
||||
private static class Ellipsis extends Array {
|
||||
private Ellipsis(PsiType original, Type componentType) {
|
||||
private Ellipsis(@NotNull PsiType original, @NotNull Type componentType) {
|
||||
super(original, componentType);
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ public class CanonicalTypes {
|
||||
private final boolean myIsExtending;
|
||||
private final Type myBound;
|
||||
|
||||
private WildcardType(PsiType original, boolean isExtending, Type bound) {
|
||||
private WildcardType(@NotNull PsiType original, boolean isExtending, @Nullable Type bound) {
|
||||
super(original.getAnnotations());
|
||||
myIsExtending = isExtending;
|
||||
myBound = bound;
|
||||
@@ -176,7 +177,7 @@ public class CanonicalTypes {
|
||||
private final String myPresentableText;
|
||||
private final String myCanonicalText;
|
||||
|
||||
private UnresolvedType(PsiType original) {
|
||||
private UnresolvedType(@NotNull PsiType original) {
|
||||
myPresentableText = original.getPresentableText();
|
||||
myCanonicalText = original.getCanonicalText(true);
|
||||
}
|
||||
@@ -203,7 +204,7 @@ public class CanonicalTypes {
|
||||
private final String myClassQName;
|
||||
private final Map<String, Type> mySubstitutor;
|
||||
|
||||
private ClassType(PsiType original, String classQName, Map<String, Type> substitutor) {
|
||||
private ClassType(@NotNull PsiType original, @NotNull String classQName, @NotNull Map<String, Type> substitutor) {
|
||||
super(original.getAnnotations());
|
||||
myPresentableText = original.getPresentableText();
|
||||
myClassQName = classQName;
|
||||
|
||||
@@ -89,11 +89,14 @@ public class ComparisonFailureData {
|
||||
if (actualFilePath != null) {
|
||||
attrs.put("actualFile", actualFilePath);
|
||||
}
|
||||
final int expectedIdx = trace.indexOf("expected");
|
||||
final int expectedIdx = trace.indexOf("expected:<");
|
||||
final String comparisonFailureMessage;
|
||||
if (expectedIdx > 0) {
|
||||
comparisonFailureMessage = trace.substring(0, expectedIdx);
|
||||
}
|
||||
else if (failureIdx > -1) {
|
||||
comparisonFailureMessage = trace.substring(0, failureIdx + failureMessageLength);
|
||||
}
|
||||
else {
|
||||
comparisonFailureMessage = (failureMessageLength > 0 ? failureMessage + "\n" : "") + "Comparison Failure: ";
|
||||
}
|
||||
@@ -109,7 +112,8 @@ public class ComparisonFailureData {
|
||||
if (!isAssertionError(throwable.getClass()) && !isAssertionError(throwableCause != null ? throwableCause.getClass() : null)) {
|
||||
attrs.put("error", "true");
|
||||
}
|
||||
attrs.put("message", failureMessage != null ? failureMessage : "");
|
||||
attrs.put("message", failureIdx > -1 ? trace.substring(0, failureIdx + failureMessageLength)
|
||||
: failureMessage != null ? failureMessage : "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,5 +44,6 @@
|
||||
<orderEntry type="module" module-name="java-decompiler-plugin" scope="TEST" />
|
||||
<orderEntry type="module" module-name="RegExpSupport" scope="TEST" />
|
||||
<orderEntry type="module" module-name="spellchecker" scope="TEST" />
|
||||
<orderEntry type="module" module-name="util-tests" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,6 @@
|
||||
public class A {
|
||||
public void method() {
|
||||
if (true) { foo(); }
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class A {
|
||||
public void method() {
|
||||
if (true) foo();
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
import <caret>
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
public class A{
|
||||
public void method() <caret> {}
|
||||
public void method() <caret>x {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import java.lang.Exception;
|
||||
|
||||
/*
|
||||
* Copyright 2000-2012 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.
|
||||
*/
|
||||
public class A{
|
||||
public void method(){
|
||||
try{
|
||||
String str = "";
|
||||
}
|
||||
catch (Exception e) {}
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Foo {
|
||||
public void get(MyEnum e) {
|
||||
switch (e) {
|
||||
case <caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
FOO, BAR, GOO
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
public class MainClass1 {
|
||||
|
||||
public void main(Object o) {
|
||||
((Ma<caret>) o).zoo();
|
||||
}
|
||||
|
||||
void zoo() {}
|
||||
|
||||
}
|
||||
|
||||
class MainClass2 {
|
||||
void zoo() {}
|
||||
}
|
||||
|
||||
class Maa {
|
||||
void zoo2() {}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
public S<caret> get() {
|
||||
return new MyStringBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
class MyStringBuffer extends StringBuffer implements SomeInterface<String> {}
|
||||
interface SomeInterface<T> {}
|
||||
class SomeOtherClass {}
|
||||
@@ -0,0 +1,16 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Foo {
|
||||
|
||||
Map<String, Integer> foo() {
|
||||
return Bar.new<caret>
|
||||
}
|
||||
}
|
||||
|
||||
class Bar {
|
||||
static <T, V> HashMap<T, V> newMap() {}
|
||||
static <E> ArrayList<E> newList() {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
class Foo {
|
||||
void m() {
|
||||
Map<String, Integer> m = Collections.emptyMap();<caret>
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.Map;
|
||||
|
||||
class Foo {
|
||||
void m() {
|
||||
Map<String, Integer> m = emptyM<caret>
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Main {
|
||||
|
||||
public Object main(Object o) {
|
||||
return ((Main<caret>) o).zoo();
|
||||
}
|
||||
|
||||
void zoo() {}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Main {
|
||||
|
||||
public Object main(Object o) {
|
||||
return ((<caret>) o).zoo();
|
||||
}
|
||||
|
||||
void zoo() {}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class Main {
|
||||
|
||||
public <caret> main() {
|
||||
if (equals(2)) {
|
||||
return "a";
|
||||
} else {
|
||||
return new StringBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
class Test {
|
||||
{
|
||||
Arrays.asList<error descr="Formal varargs element type is inaccessible here">(new Outer.B(), new Outer.C())</error>;
|
||||
}
|
||||
}
|
||||
|
||||
class Outer {
|
||||
private static class A {}
|
||||
public static class B extends A {}
|
||||
public static class C extends A {}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user