Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-08-18 17:59:11 +03:00
578 changed files with 10897 additions and 7137 deletions
+16
View File
@@ -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>
+4 -4
View File
@@ -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 />
+5
View File
@@ -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" />
@@ -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
View File
@@ -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.
+4
View File
@@ -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")
+1 -1
View File
@@ -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);
@@ -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);
@@ -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;
@@ -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();
}
@@ -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) {
@@ -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();
}
@@ -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);
}
}
}
@@ -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
@@ -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,
@@ -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);
@@ -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;
@@ -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);
}
@@ -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);
}
}
}
@@ -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),
@@ -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) {
@@ -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));
}
}
@@ -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)
@@ -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) {
@@ -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;
}
}
@@ -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);
}
});
@@ -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
@@ -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) {
@@ -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) {
@@ -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);
}
}
@@ -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;
@@ -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() {
@@ -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
@@ -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) {
@@ -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();
@@ -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;
}
@@ -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) {
@@ -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 {
@@ -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);
}
}
}
@@ -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 : "");
}
}
+1
View File
@@ -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>
}
}
@@ -0,0 +1,11 @@
class Foo {
public void get(MyEnum e) {
switch (e) {
case <caret>
}
}
}
enum MyEnum {
FOO, BAR, GOO
}
@@ -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() {}
}
@@ -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>
}
}
@@ -0,0 +1,9 @@
public class Main {
public Object main(Object o) {
return ((Main<caret>) o).zoo();
}
void zoo() {}
}
@@ -0,0 +1,9 @@
public class Main {
public Object main(Object o) {
return ((<caret>) o).zoo();
}
void zoo() {}
}
@@ -0,0 +1,13 @@
import java.lang.StringBuilder;
public class Main {
public <caret> main() {
if (equals(2)) {
return "a";
} else {
return new StringBuilder();
}
}
}
@@ -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