mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master' into develar/is
# Conflicts: # platform/lang-impl/src/com/intellij/codeInspection/actions/ViewOfflineResultsAction.java
This commit is contained in:
Generated
+2
-2
@@ -1,8 +1,7 @@
|
||||
<component name="libraryTable">
|
||||
<library name="Mocks">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/easymock.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/easymockclassextension.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/easymock-3.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
|
||||
@@ -10,6 +9,7 @@
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/easymock-3.4-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-2.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-junit4-2.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/dev/jmock-legacy-2.5.1.jar!/" />
|
||||
|
||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="pty4j">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.7.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/pty4j-0.7.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.7-src.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/pty4j-0.7.1-src.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
|
||||
@@ -279,7 +279,7 @@ libraryLicense(name: "Plexus Utils", libraryName: "plexus-utils-1.5.5.jar", vers
|
||||
libraryLicense(name: "pockets", attachedTo: "python-helpers", version: "0.2.4", license: "BSD", url: "http://pockets.readthedocs.org/")
|
||||
libraryLicense(name: "protobuf", version: "2.5.0", license: "New BSD", url: "http://code.google.com/p/protobuf/", licenseUrl: "https://github.com/google/protobuf/blob/master/LICENSE")
|
||||
libraryLicense(name: "proxy-vole", libraryName: "proxy-vole", version: "20131209", license: "New BSD License", url: "http://code.google.com/p/proxy-vole/", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
|
||||
libraryLicense(name: "pty4j", libraryName: "pty4j", version: "0.7", license: "Eclipse Public License v1.0", url: "https://github.com/traff/pty4j")
|
||||
libraryLicense(name: "pty4j", libraryName: "pty4j", version: "0.7.1", license: "Eclipse Public License v1.0", url: "https://github.com/traff/pty4j")
|
||||
libraryLicense(name: "PureJavaComm", libraryName: "purejavacomm", version: "0.0.16", license: "BSD", url: "http://www.sparetimelabs.com/purejavacomm")
|
||||
libraryLicense(name: "ReflectASM", libraryName: "reflectasm-1.0.7.jar", version: "1.0.7", license: "BSD", url: "https://github.com/EsotericSoftware/reflectasm", licenseUrl: "http://opensource.org/licenses/BSD-3-Clause")
|
||||
libraryLicense(name: "Relax NG Object Model", libraryName: "rngom-20051226-patched.jar", license: "MIT", url: "http://java.net/projects/rngom/", licenseUrl: "http://www.opensource.org/licenses/mit-license.php")
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.intellij.debugger.engine.JVMNameUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.MethodBytecodeUtil;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
@@ -32,6 +34,11 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class JumpToObjectAction extends DebuggerAction{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.JumpToObjectAction");
|
||||
@@ -96,7 +103,35 @@ public class JumpToObjectAction extends DebuggerAction{
|
||||
}
|
||||
if(type instanceof ClassType) {
|
||||
final ClassType clsType = (ClassType)type;
|
||||
final Location location = ContainerUtil.getFirstItem(clsType.allLineLocations());
|
||||
Location lambdaLocation = null;
|
||||
if (DebuggerUtilsEx.isLambdaClassName(clsType.name())) {
|
||||
List<Method> notConstructorMethods = ContainerUtil.filter(clsType.methods(), m -> !m.isConstructor());
|
||||
if (notConstructorMethods.size() == 1) {
|
||||
AtomicReference<Location> locationRef = new AtomicReference<>();
|
||||
MethodBytecodeUtil.visit(clsType, notConstructorMethods.get(0), new MethodVisitor(Opcodes.ASM5) {
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
||||
ReferenceType cls = ContainerUtil.getFirstItem(clsType.virtualMachine().classesByName(owner));
|
||||
if (cls != null) {
|
||||
Method method = ContainerUtil.getFirstItem(cls.methodsByName(name));
|
||||
if (method != null) {
|
||||
try {
|
||||
Location loc = ContainerUtil.getFirstItem(method.allLineLocations());
|
||||
if (loc != null) {
|
||||
locationRef.set(loc);
|
||||
}
|
||||
}
|
||||
catch (AbsentInformationException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
lambdaLocation = locationRef.get();
|
||||
}
|
||||
}
|
||||
final Location location = lambdaLocation != null ? lambdaLocation : ContainerUtil.getFirstItem(clsType.allLineLocations());
|
||||
if (location != null) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
|
||||
@Override
|
||||
@@ -118,10 +153,7 @@ public class JumpToObjectAction extends DebuggerAction{
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotPreparedException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
catch (AbsentInformationException e) {
|
||||
catch (ClassNotPreparedException | AbsentInformationException e) {
|
||||
LOG.debug(e);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -150,13 +150,12 @@ public class LocalVariablesUtil {
|
||||
|
||||
com.sun.jdi.Method method = frameProxy.location().method();
|
||||
final int firstLocalVariableSlot = getFirstLocalsSlot(method);
|
||||
final int firstArgsSlot = getFirstArgsSlot(method);
|
||||
|
||||
// gather code variables names
|
||||
MultiMap<Integer, String> namesMap = calcNames(new SimpleStackFrameContext(frameProxy, process), firstLocalVariableSlot, firstArgsSlot);
|
||||
MultiMap<Integer, String> namesMap = calcNames(new SimpleStackFrameContext(frameProxy, process), firstLocalVariableSlot);
|
||||
|
||||
// first add arguments
|
||||
int slot = firstArgsSlot;
|
||||
int slot = getFirstArgsSlot(method);
|
||||
List<String> typeNames = method.argumentTypeNames();
|
||||
List<Value> argValues = frameProxy.getArgumentValues();
|
||||
for (int i = 0; i < argValues.size(); i++) {
|
||||
@@ -317,9 +316,7 @@ public class LocalVariablesUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MultiMap<Integer, String> calcNames(@NotNull final StackFrameContext context,
|
||||
final int firstLocalsSlot,
|
||||
final int firstArgsSlot) {
|
||||
private static MultiMap<Integer, String> calcNames(@NotNull final StackFrameContext context, final int firstLocalsSlot) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<MultiMap<Integer, String>>() {
|
||||
@Override
|
||||
public MultiMap<Integer, String> compute() {
|
||||
@@ -329,7 +326,7 @@ public class LocalVariablesUtil {
|
||||
PsiElement method = DebuggerUtilsEx.getContainingMethod(element);
|
||||
if (method != null) {
|
||||
MultiMap<Integer, String> res = new MultiMap<>();
|
||||
int slot = Math.max(0, firstArgsSlot + firstLocalsSlot - getFirstLocalsSlot(method));
|
||||
int slot = Math.max(0, firstLocalsSlot - getParametersStackSize(method));
|
||||
for (PsiParameter parameter : DebuggerUtilsEx.getParameters(method)) {
|
||||
res.putValue(slot, parameter.getName());
|
||||
slot += getTypeSlotSize(parameter.getType());
|
||||
@@ -481,11 +478,8 @@ public class LocalVariablesUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static int getFirstLocalsSlot(PsiElement method) {
|
||||
private static int getParametersStackSize(PsiElement method) {
|
||||
int startSlot = 0;
|
||||
if (method instanceof PsiModifierListOwner) {
|
||||
startSlot = ((PsiModifierListOwner)method).hasModifierProperty(PsiModifier.STATIC) ? 0 : 1;
|
||||
}
|
||||
for (PsiParameter parameter : DebuggerUtilsEx.getParameters(method)) {
|
||||
startSlot += getTypeSlotSize(parameter.getType());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.debugger.jdi;
|
||||
|
||||
import com.sun.jdi.ClassType;
|
||||
import com.sun.jdi.Method;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public class MethodBytecodeUtil {
|
||||
private MethodBytecodeUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to use ASM MethodVisitor with jdi method bytecode
|
||||
*/
|
||||
public static void visit(ClassType classType, Method method, MethodVisitor methodVisitor) {
|
||||
try {
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos)) {
|
||||
dos.writeInt(0xCAFEBABE); // magic
|
||||
dos.writeInt(Opcodes.V1_8); // version
|
||||
dos.writeShort(classType.constantPoolCount()); // constant_pool_count
|
||||
dos.write(classType.constantPool()); // constant_pool
|
||||
|
||||
// we generate and put code attribute right after the constant pool
|
||||
byte[] bytecodes = method.bytecodes();
|
||||
int codeSize = dos.size();
|
||||
dos.writeShort(0); // max_stack
|
||||
dos.writeShort(0); // max_locals
|
||||
dos.writeInt(bytecodes.length); // code_length
|
||||
dos.write(bytecodes); // code
|
||||
dos.writeShort(0); // exception_table_length
|
||||
dos.writeShort(0); // attributes_count
|
||||
codeSize = dos.size() - codeSize;
|
||||
|
||||
ClassReader clsReader = new ClassReader(bos.toByteArray());
|
||||
ClassWriter clsWriter = new ClassWriter(clsReader, 0);
|
||||
clsWriter.visit(Opcodes.V1_8,
|
||||
Opcodes.ACC_PUBLIC,
|
||||
classType.name(),
|
||||
classType.signature(),
|
||||
classType.superclass().name(),
|
||||
classType.interfaces().stream().map(ReferenceType::name).toArray(String[]::new));
|
||||
MethodVisitor mv = clsWriter.visitMethod(Opcodes.ACC_PUBLIC, method.name(), method.signature(), method.signature(), null);
|
||||
mv.visitAttribute(createCode(clsReader, codeSize));
|
||||
|
||||
new ClassReader(clsWriter.toByteArray()).accept(new ClassVisitor(Opcodes.ASM5) {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
return methodVisitor;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static Attribute createCode(ClassReader cr, int len) {
|
||||
return new Attribute("Code") {
|
||||
@Override
|
||||
public Attribute read(ClassReader cr, int off, int len, char[] buf, int codeOff, Label[] labels) {
|
||||
return super.read(cr, off, len, buf, codeOff, labels);
|
||||
}
|
||||
}.read(cr, cr.header, len, null, 0, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -156,7 +156,6 @@ public abstract class JavaTestFrameworkRunnableState<T extends
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
Runnable runnable = () -> {
|
||||
root.flush();
|
||||
deleteTempFiles();
|
||||
clear();
|
||||
};
|
||||
|
||||
+4
-2
@@ -19,7 +19,6 @@ import com.intellij.codeInsight.TestFrameworks;
|
||||
import com.intellij.codeInsight.actions.FormatChangedTextUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
@@ -28,6 +27,7 @@ import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
@@ -99,7 +99,9 @@ public class TestDiscoverySearchHelper {
|
||||
});
|
||||
}
|
||||
|
||||
return patterns;
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project);
|
||||
return new HashSet<>(ContainerUtil.filter(patterns, fqn -> psiFacade.findClass(fqn, searchScope) != null));
|
||||
}
|
||||
|
||||
private static void collectPatterns(final Project project,
|
||||
|
||||
@@ -56,9 +56,15 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
private final JPanel myJdkPanel;
|
||||
|
||||
public SdkSettingsStep(SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder,
|
||||
@NotNull Condition<SdkTypeId> sdkFilter) {
|
||||
@NotNull Condition<SdkTypeId> sdkTypeIdFilter) {
|
||||
|
||||
this(settingsStep.getContext(), moduleBuilder, sdkFilter);
|
||||
this(settingsStep, moduleBuilder, sdkTypeIdFilter, null);
|
||||
}
|
||||
|
||||
public SdkSettingsStep(SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder,
|
||||
@NotNull Condition<SdkTypeId> sdkTypeIdFilter, @Nullable Condition<Sdk> sdkFilter) {
|
||||
|
||||
this(settingsStep.getContext(), moduleBuilder, sdkTypeIdFilter, sdkFilter);
|
||||
if (!isEmpty()) {
|
||||
settingsStep.addSettingsField(getSdkFieldLabel(settingsStep.getContext().getProject()), myJdkPanel);
|
||||
}
|
||||
@@ -66,7 +72,8 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
|
||||
public SdkSettingsStep(WizardContext context,
|
||||
@NotNull ModuleBuilder moduleBuilder,
|
||||
@NotNull Condition<SdkTypeId> sdkFilter) {
|
||||
@NotNull Condition<SdkTypeId> sdkTypeIdFilter,
|
||||
@Nullable Condition<Sdk> sdkFilter) {
|
||||
myModuleBuilder = moduleBuilder;
|
||||
|
||||
myWizardContext = context;
|
||||
@@ -74,7 +81,11 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
Project project = myWizardContext.getProject();
|
||||
myModel.reset(project);
|
||||
|
||||
myJdkComboBox = new JdkComboBox(myModel, sdkFilter, sdkFilter, false);
|
||||
if (sdkFilter == null) {
|
||||
sdkFilter = JdkComboBox.getSdkFilter(sdkTypeIdFilter);
|
||||
}
|
||||
|
||||
myJdkComboBox = new JdkComboBox(myModel, sdkFilter, sdkTypeIdFilter, false);
|
||||
myJdkPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
final PropertiesComponent component = project == null ? PropertiesComponent.getInstance() : PropertiesComponent.getInstance(project);
|
||||
@@ -91,7 +102,7 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
}
|
||||
});
|
||||
|
||||
Sdk sdk = getPreselectedSdk(project, component.getValue(selectedJdkProperty), sdkFilter);
|
||||
Sdk sdk = getPreselectedSdk(project, component.getValue(selectedJdkProperty), sdkTypeIdFilter);
|
||||
myJdkComboBox.setSelectedJdk(sdk);
|
||||
|
||||
JButton button = new JButton("Ne\u001Bw...");
|
||||
@@ -103,7 +114,7 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
myJdkPanel.add(myJdkComboBox, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, CENTER, HORIZONTAL, JBUI.emptyInsets(), 0, 0));
|
||||
myJdkPanel.add(myJdkComboBox.getSetUpButton(), new GridBagConstraints(1, 0, 1, 1, 0, 0, WEST, NONE, JBUI.insetsLeft(4), 0, 0));
|
||||
if (myJdkComboBox.getItemCount() == 0) {
|
||||
SdkType type = ContainerUtil.find(SdkType.getAllTypes(), sdkFilter);
|
||||
SdkType type = ContainerUtil.find(SdkType.getAllTypes(), sdkTypeIdFilter);
|
||||
if (type != null && type.getDownloadSdkUrl() != null) {
|
||||
HyperlinkLabel label = new HyperlinkLabel("Download " + type.getPresentableName());
|
||||
label.setHyperlinkTarget(type.getDownloadSdkUrl());
|
||||
|
||||
@@ -55,7 +55,7 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
private static final Icon EMPTY_ICON = EmptyIcon.create(1, 16);
|
||||
|
||||
@Nullable
|
||||
private final Condition<SdkTypeId> myFilter;
|
||||
private final Condition<Sdk> myFilter;
|
||||
@Nullable
|
||||
private final Condition<SdkTypeId> myCreationFilter;
|
||||
private JButton mySetUpButton;
|
||||
@@ -66,11 +66,11 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
|
||||
public JdkComboBox(@NotNull final ProjectSdksModel jdkModel,
|
||||
@Nullable Condition<SdkTypeId> filter) {
|
||||
this(jdkModel, filter, filter, false);
|
||||
this(jdkModel, getSdkFilter(filter), filter, false);
|
||||
}
|
||||
|
||||
public JdkComboBox(@NotNull final ProjectSdksModel jdkModel,
|
||||
@Nullable Condition<SdkTypeId> filter,
|
||||
@Nullable Condition<Sdk> filter,
|
||||
@Nullable Condition<SdkTypeId> creationFilter,
|
||||
boolean addSuggestedItems) {
|
||||
super(new JdkComboBoxModel(jdkModel, filter, addSuggestedItems));
|
||||
@@ -280,7 +280,7 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
final ProjectSdksModel projectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel();
|
||||
List<Sdk> projectJdks = new ArrayList<Sdk>(projectJdksModel.getProjectSdks().values());
|
||||
if (myFilter != null) {
|
||||
projectJdks = ContainerUtil.filter(projectJdks, getSdkFilter(myFilter));
|
||||
projectJdks = ContainerUtil.filter(projectJdks, myFilter);
|
||||
}
|
||||
Collections.sort(projectJdks, (o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
|
||||
for (Sdk projectJdk : projectJdks) {
|
||||
@@ -289,11 +289,11 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
}
|
||||
|
||||
private static class JdkComboBoxModel extends DefaultComboBoxModel {
|
||||
public JdkComboBoxModel(final ProjectSdksModel jdksModel, @Nullable Condition<SdkTypeId> sdkFilter, boolean addSuggested) {
|
||||
public JdkComboBoxModel(final ProjectSdksModel jdksModel, @Nullable Condition<Sdk> sdkFilter, boolean addSuggested) {
|
||||
Sdk[] jdks = jdksModel.getSdks();
|
||||
Arrays.sort(jdks, (s1, s2) -> s1.getName().compareToIgnoreCase(s2.getName()));
|
||||
for (Sdk jdk : jdks) {
|
||||
if (sdkFilter == null || sdkFilter.value(jdk.getSdkType())) {
|
||||
if (sdkFilter == null || sdkFilter.value(jdk)) {
|
||||
addElement(new JdkComboBoxItem(jdk));
|
||||
}
|
||||
}
|
||||
@@ -302,10 +302,10 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
}
|
||||
}
|
||||
|
||||
protected void addSuggestedItems(@Nullable Condition<SdkTypeId> sdkFilter, Sdk[] jdks) {
|
||||
protected void addSuggestedItems(@Nullable Condition<Sdk> sdkFilter, Sdk[] jdks) {
|
||||
SdkType[] types = SdkType.getAllTypes();
|
||||
for (SdkType type : types) {
|
||||
if (sdkFilter == null || sdkFilter.value(type) && ContainerUtil.find(jdks, sdk -> sdk.getSdkType() == type) == null) {
|
||||
if (sdkFilter == null || ContainerUtil.find(jdks, sdkFilter) == null) {
|
||||
String homePath = type.suggestHomePath();
|
||||
if (homePath != null && type.isValidSdkHome(homePath)) {
|
||||
addElement(new SuggestedJdkItem(type, homePath));
|
||||
@@ -321,7 +321,7 @@ public class JdkComboBox extends ComboBoxWithWidePopup {
|
||||
}
|
||||
}
|
||||
|
||||
private static Condition<Sdk> getSdkFilter(@Nullable final Condition<SdkTypeId> filter) {
|
||||
public static Condition<Sdk> getSdkFilter(@Nullable final Condition<SdkTypeId> filter) {
|
||||
return filter == null ? Conditions.<Sdk>alwaysTrue() : (Condition<Sdk>)sdk -> filter.value(sdk.getSdkType());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -255,8 +255,7 @@ public abstract class QuickFixFactory {
|
||||
public abstract IntentionAction createSafeDeleteFix(@NotNull PsiElement element);
|
||||
|
||||
@Nullable
|
||||
public abstract List<LocalQuickFix> registerOrderEntryFixes(@NotNull QuickFixActionRegistrar registrar,
|
||||
@NotNull PsiReference reference);
|
||||
public abstract List<LocalQuickFix> registerOrderEntryFixes(@NotNull QuickFixActionRegistrar registrar, @NotNull PsiReference reference);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createAddMissingRequiredAnnotationParametersFix(@NotNull PsiAnnotation annotation,
|
||||
@@ -274,5 +273,5 @@ public abstract class QuickFixFactory {
|
||||
@NotNull
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -1521,6 +1521,9 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
else {
|
||||
aClass = PsiTreeUtil.getParentOfType(expr, PsiClass.class);
|
||||
if (aClass instanceof PsiAnonymousClass && PsiTreeUtil.isAncestor(((PsiAnonymousClass)aClass).getArgumentList(), expr, false)) {
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
|
||||
}
|
||||
}
|
||||
if (aClass == null) return null;
|
||||
|
||||
@@ -2981,7 +2984,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
LAMBDA_EXPRESSIONS(LanguageLevel.JDK_1_8, "feature.lambda.expressions"),
|
||||
TYPE_ANNOTATIONS(LanguageLevel.JDK_1_8, "feature.type.annotations"),
|
||||
RECEIVERS(LanguageLevel.JDK_1_8, "feature.type.receivers"),
|
||||
REFS_AS_RESOURCE(LanguageLevel.JDK_1_9, "feature.try.with.resources.refs");
|
||||
REFS_AS_RESOURCE(LanguageLevel.JDK_1_9, "feature.try.with.resources.refs"),
|
||||
MODULES(LanguageLevel.JDK_1_9, "feature.modules");
|
||||
|
||||
private final LanguageLevel level;
|
||||
private final String key;
|
||||
@@ -3007,4 +3011,4 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-5
@@ -1598,19 +1598,27 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkReceiverType(parameter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitModule(PsiJavaModule module) {
|
||||
super.visitModule(module);
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(checkFeature(module, Feature.MODULES));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileName(module, myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileDuplicates(module, myFile));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(ModuleHighlightUtil.checkFileLocation(module, myFile));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HighlightInfo checkFeature(@NotNull PsiElement element, @NotNull Feature feature) {
|
||||
return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
|
||||
}
|
||||
|
||||
protected void prepareToRunAsInspection(@NotNull HighlightInfoHolder holder) {
|
||||
myHolder = holder;
|
||||
PsiFile file = holder.getContextFile();
|
||||
JavaSdkVersion sdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(file);
|
||||
|
||||
final PsiFile file = holder.getContextFile();
|
||||
myHolder = holder;
|
||||
myFile = file;
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(file);
|
||||
myJavaSdkVersion = ObjectUtils.notNull(JavaVersionService.getInstance().getJavaSdkVersion(file),
|
||||
JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
|
||||
|
||||
myJavaSdkVersion = sdkVersion != null ? sdkVersion : JavaSdkVersion.fromLanguageLevel(myLanguageLevel);
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MoveFileFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.impl.scopes.ModulesScope;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaModule;
|
||||
import com.intellij.psi.PsiJavaModuleReference;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class ModuleHighlightUtil {
|
||||
private static final String MODULE_FILE_NAME = "module-info.java";
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkFileName(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
|
||||
if (!MODULE_FILE_NAME.equals(file.getName())) {
|
||||
String message = JavaErrorMessages.message("module.file.wrong.name");
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create();
|
||||
QuickFixAction.registerQuickFixAction(info, factory().createRenameFileFix(MODULE_FILE_NAME));
|
||||
return info;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkFileDuplicates(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile != null) {
|
||||
Project project = file.getProject();
|
||||
Module module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(vFile);
|
||||
if (module != null) {
|
||||
Collection<VirtualFile> others =
|
||||
FilenameIndex.getVirtualFilesByName(project, MODULE_FILE_NAME, new ModulesScope(Collections.singleton(module), project));
|
||||
if (others.size() > 1) {
|
||||
String message = JavaErrorMessages.message("module.file.duplicate");
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create();
|
||||
//todo show duplicates quick fix
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkFileLocation(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile != null) {
|
||||
VirtualFile root = ProjectFileIndex.SERVICE.getInstance(file.getProject()).getSourceRootForFile(vFile);
|
||||
if (root != null && !root.equals(vFile.getParent())) {
|
||||
String message = JavaErrorMessages.message("module.file.wrong.location");
|
||||
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(range(element)).description(message).create();
|
||||
QuickFixAction.registerQuickFixAction(info, new MoveFileFix(vFile, root));
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static QuickFixFactory factory() {
|
||||
return QuickFixFactory.getInstance();
|
||||
}
|
||||
|
||||
private static TextRange range(PsiJavaModule module) {
|
||||
PsiJavaModuleReference name = module.getNameElement();
|
||||
return name != null ? new TextRange(module.getTextOffset(), name.getTextRange().getEndOffset()) : module.getTextRange();
|
||||
}
|
||||
}
|
||||
-6
@@ -406,12 +406,6 @@ class PostHighlightingVisitor {
|
||||
@NotNull PsiIdentifier identifier,
|
||||
@NotNull ProgressIndicator progress) {
|
||||
if (!myRefCountHolder.isReferenced(parameter) && !UnusedSymbolUtil.isImplicitUsage(myProject, parameter, progress)) {
|
||||
//parameter is defined by functional interface
|
||||
final PsiElement declarationScope = parameter.getDeclarationScope();
|
||||
if (declarationScope instanceof PsiMethod &&
|
||||
myRefCountHolder.isReferencedByMethodReference((PsiMethod)declarationScope, myLanguageLevel)) {
|
||||
return null;
|
||||
}
|
||||
String message = JavaErrorMessages.message("parameter.is.not.used", identifier.getText());
|
||||
return UnusedSymbolUtil.createUnusedSymbolInfo(identifier, message, myDeadCodeInfoType);
|
||||
}
|
||||
|
||||
-20
@@ -222,26 +222,6 @@ class RefCountHolder {
|
||||
return usedStatus == Boolean.TRUE;
|
||||
}
|
||||
|
||||
boolean isReferencedByMethodReference(@NotNull PsiMethod method, @NotNull LanguageLevel languageLevel) {
|
||||
if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return false;
|
||||
|
||||
Collection<PsiReference> array;
|
||||
synchronized (myLocalRefsMap) {
|
||||
array = myLocalRefsMap.get(method);
|
||||
}
|
||||
|
||||
if (!array.isEmpty()) {
|
||||
for (PsiReference reference : array) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element instanceof PsiMethodReferenceExpression) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isParameterUsedRecursively(@NotNull PsiElement element, @NotNull Collection<PsiReference> array) {
|
||||
if (!(element instanceof PsiParameter)) return false;
|
||||
PsiParameter parameter = (PsiParameter)element;
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class MoveFileFix implements IntentionAction {
|
||||
private final VirtualFile myFile;
|
||||
private final VirtualFile myTarget;
|
||||
|
||||
public MoveFileFix(@NotNull VirtualFile file, @NotNull VirtualFile target) {
|
||||
myFile = file;
|
||||
myTarget = target;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("move.file.to.source.root.text");
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (myFile.isValid() && myTarget.isValid()) {
|
||||
try {
|
||||
myFile.move(this, myTarget);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IncorrectOperationException("Cannot move '" + myFile.getPath() + "' into '" + myTarget.getPath() + "'", (Throwable)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+23
-10
@@ -140,14 +140,6 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
return true;
|
||||
}
|
||||
|
||||
PsiType inferenceMethodReturnType = LambdaUtil.getFunctionalInterfaceReturnType(inferredType);
|
||||
PsiType existingMethodReturnType = method.getReturnType();
|
||||
if (existingMethodReturnType == null ||
|
||||
inferenceMethodReturnType != null &&
|
||||
!PsiType.VOID.equals(inferenceMethodReturnType) && !TypeConversionUtil.isAssignable(existingMethodReturnType, inferenceMethodReturnType)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(method, aClass);
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
@@ -262,6 +254,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body == null) return null;
|
||||
|
||||
final Collection<PsiComment> comments = collectCommentsOutsideMethodBody(anonymousClass, body);
|
||||
final Project project = element.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
@@ -285,12 +278,12 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
.giveUniqueNames(project, elementFactory, lambdaExpression,
|
||||
usedLocalNames, variables.toArray(new PsiVariable[variables.size()]));
|
||||
|
||||
final PsiExpression singleExpr = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(
|
||||
lambdaExpression.getBody());
|
||||
final PsiExpression singleExpr = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(lambdaExpression.getBody());
|
||||
if (singleExpr != null) {
|
||||
lambdaExpression.getBody().replace(singleExpr);
|
||||
}
|
||||
ChangeContextUtil.decodeContextInfo(lambdaExpression, null, null);
|
||||
restoreComments(comments, lambdaExpression);
|
||||
|
||||
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
if (forceIgnoreTypeCast) {
|
||||
@@ -318,6 +311,16 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Collection<PsiComment> collectCommentsOutsideMethodBody(PsiAnonymousClass anonymousClass, PsiCodeBlock body) {
|
||||
final Collection<PsiComment> psiComments = PsiTreeUtil.findChildrenOfType(anonymousClass, PsiComment.class);
|
||||
for (Iterator<PsiComment> iterator = psiComments.iterator(); iterator.hasNext(); ) {
|
||||
if (PsiTreeUtil.isAncestor(body, iterator.next(), false)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return ContainerUtil.map(psiComments, (comment) -> (PsiComment)comment.copy());
|
||||
}
|
||||
|
||||
private static void collectLocalVariablesDefinedInsideLambda(PsiLambdaExpression lambdaExpression,
|
||||
final Set<PsiVariable> variables,
|
||||
Set<String> namesOfVariablesInTheBlock) {
|
||||
@@ -460,6 +463,16 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void restoreComments(Collection<PsiComment> comments, PsiElement lambda) {
|
||||
PsiElement anchor = PsiTreeUtil.getParentOfType(lambda, PsiStatement.class, PsiField.class);
|
||||
if (anchor == null) {
|
||||
anchor = lambda;
|
||||
}
|
||||
for (PsiComment comment : comments) {
|
||||
anchor.getParent().addBefore(comment, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ForbiddenRefsChecker extends JavaRecursiveElementWalkingVisitor {
|
||||
private boolean myBodyContainsForbiddenRefs;
|
||||
|
||||
|
||||
+1
-7
@@ -518,13 +518,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
|
||||
replace = replace.replace(cast);
|
||||
}
|
||||
|
||||
PsiElement anchor = PsiTreeUtil.getParentOfType(replace, PsiStatement.class);
|
||||
if (anchor == null) {
|
||||
anchor = replace;
|
||||
}
|
||||
for (PsiComment comment : comments) {
|
||||
anchor.getParent().addBefore(comment, anchor);
|
||||
}
|
||||
AnonymousCanBeLambdaInspection.restoreComments(comments, replace);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replace);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -81,9 +81,16 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
}
|
||||
final PsiMethodCallExpression qualifierCall = getQualifierMethodCall(methodCall);
|
||||
if (isCallOf(qualifierCall, CommonClassNames.JAVA_UTIL_COLLECTION, STREAM_METHOD, 0)) {
|
||||
holder.registerProblem(methodCall, getCallChainRange(methodCall, qualifierCall),
|
||||
"Collection.stream()." + name + "() can be replaced with Collection.forEach()",
|
||||
FOR_EACH_METHOD.equals(name) ? new CollectionForEachFix() : new CollectionForEachOrderedFix());
|
||||
String message = "Collection.stream()." + name + "() can be replaced with Collection.forEach()";
|
||||
final LocalQuickFix fix;
|
||||
if (FOR_EACH_METHOD.equals(name)) {
|
||||
fix = new CollectionForEachFix();
|
||||
}
|
||||
else {
|
||||
fix = new CollectionForEachOrderedFix();
|
||||
message += " (may change semantics)";
|
||||
}
|
||||
holder.registerProblem(methodCall, getCallChainRange(methodCall, qualifierCall), message, fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,7 +228,7 @@ public class SimplifyStreamApiCallChainsInspection extends BaseJavaBatchLocalIns
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace Collection.stream()." + FOR_EACH_ORDERED_METHOD + "() with Collection.forEach()";
|
||||
return "Replace Collection.stream()." + FOR_EACH_ORDERED_METHOD + "() with Collection.forEach() (may change semantics)";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-17
@@ -17,6 +17,7 @@ package com.intellij.codeInspection.reference;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -426,24 +427,19 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
|
||||
@Override
|
||||
public String getName() {
|
||||
if (isValid()) {
|
||||
final String[] result = new String[1];
|
||||
final Runnable runnable = () -> {
|
||||
return ReadAction.compute(() -> {
|
||||
PsiMethod psiMethod = (PsiMethod) getElement();
|
||||
if (psiMethod instanceof SyntheticElement) {
|
||||
result[0] = psiMethod.getName();
|
||||
return psiMethod.getName();
|
||||
}
|
||||
else {
|
||||
result[0] = PsiFormatUtil.formatMethod(psiMethod,
|
||||
return PsiFormatUtil.formatMethod(psiMethod,
|
||||
PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
|
||||
PsiFormatUtilBase.SHOW_TYPE
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
|
||||
return result[0];
|
||||
});
|
||||
} else {
|
||||
return super.getName();
|
||||
}
|
||||
@@ -451,16 +447,11 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
|
||||
|
||||
@Override
|
||||
public String getExternalName() {
|
||||
final String[] result = new String[1];
|
||||
final Runnable runnable = () -> {
|
||||
return ReadAction.compute(() -> {
|
||||
final PsiMethod psiMethod = (PsiMethod)getElement();
|
||||
LOG.assertTrue(psiMethod != null);
|
||||
result[0] = PsiFormatUtil.getExternalName(psiMethod, true, Integer.MAX_VALUE);
|
||||
};
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
|
||||
return result[0];
|
||||
return PsiFormatUtil.getExternalName(psiMethod, true, Integer.MAX_VALUE);
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -686,4 +677,8 @@ public class RefMethodImpl extends RefJavaElementImpl implements RefMethod {
|
||||
setFlag(isCalledOnSubClass, IS_CALLED_ON_SUBCLASS_MASK);
|
||||
}
|
||||
|
||||
private static String extractMethodName(String methodSignature) {
|
||||
final String returnTypeAndName = methodSignature.substring(0, methodSignature.indexOf('('));
|
||||
return returnTypeAndName.substring(returnTypeAndName.indexOf(' ') + 1);
|
||||
}
|
||||
}
|
||||
|
||||
+55
-41
@@ -34,10 +34,10 @@ import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.fixes.ChangeModifierFix;
|
||||
import com.siyeh.ig.psiutils.MethodUtils;
|
||||
import gnu.trove.TObjectIntHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -87,7 +87,7 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)profile.getUnwrappedTool(UnusedDeclarationInspectionBase.SHORT_NAME, holder.getFile());
|
||||
myDeadCodeInspection = tool == null ? new UnusedDeclarationInspectionBase() : tool;
|
||||
}
|
||||
private final Set<PsiClass> childMembersAreUsedOutsideMyPackage = ContainerUtil.newConcurrentSet();
|
||||
private final TObjectIntHashMap<PsiClass> maxSuggestedLevelForChildMembers = new TObjectIntHashMap<>();
|
||||
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
@@ -105,48 +105,79 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
|
||||
private void checkMember(@NotNull final PsiMember member) {
|
||||
if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) return;
|
||||
if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) return;
|
||||
final PsiClass memberClass = member.getContainingClass();
|
||||
PsiModifierList memberModifierList = member.getModifierList();
|
||||
if (memberModifierList == null) return;
|
||||
int currentLevel = PsiUtil.getAccessLevel(memberModifierList);
|
||||
int suggestedLevel = suggestLevel(member, memberClass, currentLevel);
|
||||
if (memberClass != null) {
|
||||
synchronized (maxSuggestedLevelForChildMembers) {
|
||||
int prevMax = maxSuggestedLevelForChildMembers.get(memberClass);
|
||||
maxSuggestedLevelForChildMembers.put(memberClass, Math.max(prevMax, suggestedLevel));
|
||||
}
|
||||
}
|
||||
|
||||
log(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(suggestedLevel) + "'");
|
||||
|
||||
if (suggestedLevel < currentLevel) {
|
||||
if (member instanceof PsiClass) {
|
||||
int memberMaxLevel;
|
||||
synchronized (maxSuggestedLevelForChildMembers) {
|
||||
memberMaxLevel = maxSuggestedLevelForChildMembers.get((PsiClass)member);
|
||||
}
|
||||
if (memberMaxLevel > suggestedLevel) {
|
||||
// a class can't have visibility less than its members
|
||||
return;
|
||||
}
|
||||
}
|
||||
PsiElement toHighlight = currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL ? ((PsiNameIdentifierOwner)member).getNameIdentifier() : ContainerUtil.find(
|
||||
memberModifierList.getChildren(),
|
||||
element -> element instanceof PsiKeyword && element.getText().equals(PsiUtil.getAccessModifier(currentLevel)));
|
||||
assert toHighlight != null : member +" ; " + ((PsiNameIdentifierOwner)member).getNameIdentifier() + "; "+ memberModifierList.getText();
|
||||
String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel);
|
||||
myHolder.registerProblem(toHighlight, "Access can be " + VisibilityUtil.toPresentableText(suggestedModifier), new ChangeModifierFix(suggestedModifier));
|
||||
}
|
||||
}
|
||||
|
||||
private int suggestLevel(@NotNull PsiMember member, PsiClass memberClass, int currentLevel) {
|
||||
if (member.hasModifierProperty(PsiModifier.PRIVATE) || member.hasModifierProperty(PsiModifier.NATIVE)) return currentLevel;
|
||||
if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical()) return currentLevel;
|
||||
|
||||
if (member instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)member;
|
||||
if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) {
|
||||
log(member.getName() + " overrides");
|
||||
return; // overrides
|
||||
return currentLevel; // overrides
|
||||
}
|
||||
if (MethodUtils.isOverridden(method)) {
|
||||
log(member.getName() + " overridden");
|
||||
return;
|
||||
return currentLevel;
|
||||
}
|
||||
}
|
||||
if (member instanceof PsiEnumConstant) return;
|
||||
if (member instanceof PsiEnumConstant) return currentLevel;
|
||||
if (member instanceof PsiClass && (member instanceof PsiAnonymousClass ||
|
||||
member instanceof PsiTypeParameter ||
|
||||
member instanceof PsiSyntheticClass ||
|
||||
PsiUtil.isLocalClass((PsiClass)member))) {
|
||||
return;
|
||||
return currentLevel;
|
||||
}
|
||||
final PsiClass memberClass = member.getContainingClass();
|
||||
if (memberClass != null && (memberClass.isInterface() || memberClass.isEnum() || memberClass.isAnnotationType() || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) {
|
||||
return;
|
||||
return currentLevel;
|
||||
}
|
||||
final PsiFile memberFile = member.getContainingFile();
|
||||
Project project = memberFile.getProject();
|
||||
|
||||
if (myDeadCodeInspection.isEntryPoint(member)) {
|
||||
log(member.getName() +" is entry point");
|
||||
return;
|
||||
return currentLevel;
|
||||
}
|
||||
|
||||
PsiModifierList memberModifierList = member.getModifierList();
|
||||
if (memberModifierList == null) return;
|
||||
final int currentLevel = PsiUtil.getAccessLevel(memberModifierList);
|
||||
final AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE);
|
||||
final AtomicBoolean foundUsage = new AtomicBoolean();
|
||||
PsiDirectory memberDirectory = memberFile.getContainingDirectory();
|
||||
final PsiPackage memberPackage = memberDirectory == null ? null : JavaDirectoryService.getInstance().getPackage(memberDirectory);
|
||||
log(member.getName()+ ": checking effective level for "+member);
|
||||
|
||||
AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE);
|
||||
AtomicBoolean foundUsage = new AtomicBoolean();
|
||||
boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> {
|
||||
PsiElement element = info.getElement();
|
||||
if (element == null) return true;
|
||||
@@ -165,30 +196,21 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
if (!foundUsage.get()) {
|
||||
log(member.getName() + " unused; ignore");
|
||||
return; // do not propose private for unused method
|
||||
return currentLevel; // do not propose private for unused method
|
||||
}
|
||||
|
||||
int max = maxLevel.get();
|
||||
if (max == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) {
|
||||
max = suggestPackageLocal(member);
|
||||
int suggestedLevel = maxLevel.get();
|
||||
if (suggestedLevel == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) {
|
||||
suggestedLevel = suggestPackageLocal(member);
|
||||
}
|
||||
|
||||
String maxModifier = PsiUtil.getAccessModifier(max);
|
||||
log(member.getName() + ": effective level is '" + maxModifier + "'");
|
||||
String suggestedModifier = PsiUtil.getAccessModifier(suggestedLevel);
|
||||
log(member.getName() + ": effective level is '" + suggestedModifier + "'");
|
||||
|
||||
if (max < currentLevel) {
|
||||
if (max == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL && member instanceof PsiClass && childMembersAreUsedOutsideMyPackage.contains(member)) {
|
||||
log(member.getName() + " children used outside my package; ignore");
|
||||
return; // e.g. some public method is used outside my package (without importing class)
|
||||
}
|
||||
PsiElement toHighlight = currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL ? ((PsiNameIdentifierOwner)member).getNameIdentifier() : ContainerUtil.find(
|
||||
memberModifierList.getChildren(),
|
||||
element -> element instanceof PsiKeyword && element.getText().equals(PsiUtil.getAccessModifier(currentLevel)));
|
||||
assert toHighlight != null : member +" ; " + ((PsiNameIdentifierOwner)member).getNameIdentifier() + "; "+ memberModifierList.getText();
|
||||
myHolder.registerProblem(toHighlight, "Access can be " + VisibilityUtil.toPresentableText(maxModifier), new ChangeModifierFix(maxModifier));
|
||||
}
|
||||
return suggestedLevel;
|
||||
}
|
||||
|
||||
|
||||
private boolean handleUsage(@NotNull PsiMember member,
|
||||
@Nullable PsiClass memberClass,
|
||||
@NotNull PsiFile memberFile,
|
||||
@@ -201,20 +223,12 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
if (!(psiFile instanceof PsiJavaFile)) {
|
||||
log(" refd from " + psiFile.getName() + "; set to public");
|
||||
maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
|
||||
if (memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
return false; // referenced from XML, has to be public
|
||||
}
|
||||
//int offset = info.getNavigationOffset();
|
||||
//if (offset == -1) return true;
|
||||
@PsiUtil.AccessLevel
|
||||
int level = getEffectiveLevel(element, psiFile, member, memberFile, memberClass, memberPackage);
|
||||
log(" ref in file " + psiFile.getName() + "; level = " + PsiUtil.getAccessModifier(level) + "; (" + element + ")");
|
||||
maxLevel.getAndAccumulate(level, Math::max);
|
||||
if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
|
||||
return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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,8 @@ import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaDocTokenType;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -27,6 +29,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author max
|
||||
*/
|
||||
public class JavaHighlightingLexer extends LayeredLexer {
|
||||
private boolean myAtStart = true;
|
||||
private boolean myModuleInfo = false;
|
||||
|
||||
public JavaHighlightingLexer(@NotNull LanguageLevel languageLevel) {
|
||||
super(JavaParserDefinition.createLexer(languageLevel));
|
||||
|
||||
@@ -42,4 +47,27 @@ public class JavaHighlightingLexer extends LayeredLexer {
|
||||
docLexer.registerLayer(htmlLexer, JavaDocTokenType.DOC_COMMENT_DATA);
|
||||
registerSelfStoppingLayer(docLexer, new IElementType[]{JavaDocElementType.DOC_COMMENT}, IElementType.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
IElementType t = super.getTokenType();
|
||||
|
||||
if (myAtStart && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(t)) {
|
||||
myAtStart = false;
|
||||
myModuleInfo = t == JavaTokenType.IDENTIFIER && PsiKeyword.MODULE.equals(getTokenText());
|
||||
}
|
||||
|
||||
if (myModuleInfo && t == JavaTokenType.IDENTIFIER) {
|
||||
String text = getTokenText();
|
||||
if (PsiKeyword.MODULE.equals(text)) t = JavaTokenType.MODULE_KEYWORD;
|
||||
else if (PsiKeyword.REQUIRES.equals(text)) t = JavaTokenType.REQUIRES_KEYWORD;
|
||||
else if (PsiKeyword.EXPORTS.equals(text)) t = JavaTokenType.EXPORTS_KEYWORD;
|
||||
else if (PsiKeyword.USES.equals(text)) t = JavaTokenType.USES_KEYWORD;
|
||||
else if (PsiKeyword.PROVIDES.equals(text)) t = JavaTokenType.PROVIDES_KEYWORD;
|
||||
else if (PsiKeyword.TO.equals(text)) t = JavaTokenType.TO_KEYWORD;
|
||||
else if (PsiKeyword.WITH.equals(text)) t = JavaTokenType.WITH_KEYWORD;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -50,7 +50,8 @@ public class AddMethodQualifierFix implements IntentionAction {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
String text = QuickFixBundle.message("add.method.qualifier.fix.text", myCandidates.size() > 1 ? "" : myCandidates.get(0).getName());
|
||||
final List<PsiVariable> candidates = getOrFindCandidates();
|
||||
String text = QuickFixBundle.message("add.method.qualifier.fix.text", candidates.size() > 1 ? "" : candidates.get(0).getName());
|
||||
if (myCandidates.size() > 1) {
|
||||
text += "...";
|
||||
}
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -167,8 +167,7 @@ public class JavaElementSignatureProvider extends AbstractElementSignatureProvid
|
||||
@Nullable StringBuilder processingInfoStorage)
|
||||
{
|
||||
if (type.equals("imports")) {
|
||||
if (!(file instanceof PsiJavaFile)) return null;
|
||||
return ((PsiJavaFile)file).getImportList();
|
||||
return file instanceof PsiJavaFile ? ((PsiJavaFile)file).getImportList() : null;
|
||||
}
|
||||
else if (type.equals("method")) {
|
||||
String name = tokenizer.nextToken();
|
||||
|
||||
@@ -71,7 +71,6 @@ import java.util.regex.Pattern;
|
||||
public class JavaDocInfoGenerator {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.javadoc.JavaDocInfoGenerator");
|
||||
|
||||
@NonNls private static final Pattern ourNotDot = Pattern.compile("[^.]");
|
||||
@NonNls private static final Pattern ourWhitespaces = Pattern.compile("[ \\n\\r\\t]+");
|
||||
@NonNls private static final Pattern ourRelativeHtmlLinks = Pattern.compile("<A.*?HREF=\"([^\":]*)\"",
|
||||
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
|
||||
@@ -1408,8 +1407,7 @@ public class JavaDocInfoGenerator {
|
||||
return "";
|
||||
}
|
||||
|
||||
//noinspection ReplaceAllDot
|
||||
return "../" + ourNotDot.matcher(qName).replaceAll("").replaceAll(".", "../");
|
||||
return StringUtil.repeat("../", StringUtil.countChars(qName, '.') + 1);
|
||||
}
|
||||
|
||||
private void generateValue(StringBuilder buffer,
|
||||
|
||||
+10
-8
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextBase;
|
||||
import com.intellij.codeInspection.reference.*;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
|
||||
@@ -35,7 +36,6 @@ import com.intellij.psi.search.searches.AllOverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.containers.BidirectionalMap;
|
||||
import org.jdom.Element;
|
||||
@@ -138,13 +138,15 @@ public class EmptyMethodInspection extends GlobalJavaBatchInspectionTool {
|
||||
if (message != null) {
|
||||
final ArrayList<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
|
||||
fixes.add(getFix(processor, needToDeleteHierarchy));
|
||||
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(refMethod.getElement(), qualifiedName -> {
|
||||
fixes.add(SpecialAnnotationsUtilBase.createAddToSpecialAnnotationsListQuickFix(
|
||||
QuickFixBundle.message("fix.add.special.annotation.text", qualifiedName),
|
||||
QuickFixBundle.message("fix.add.special.annotation.family"),
|
||||
EXCLUDE_ANNOS, qualifiedName, refMethod.getElement()));
|
||||
return true;
|
||||
});
|
||||
if (globalContext instanceof GlobalInspectionContextBase && ((GlobalInspectionContextBase)globalContext).getCurrentProfile().getSingleTool() == null) {
|
||||
SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(refMethod.getElement(), qualifiedName -> {
|
||||
fixes.add(SpecialAnnotationsUtilBase.createAddToSpecialAnnotationsListQuickFix(
|
||||
QuickFixBundle.message("fix.add.special.annotation.text", qualifiedName),
|
||||
QuickFixBundle.message("fix.add.special.annotation.family"),
|
||||
EXCLUDE_ANNOS, qualifiedName, refMethod.getElement()));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
final ProblemDescriptor descriptor = manager.createProblemDescriptor(refMethod.getElement().getNavigationElement(), message, false,
|
||||
fixes.toArray(new LocalQuickFix[fixes.size()]),
|
||||
|
||||
+9
-2
@@ -19,10 +19,14 @@ import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeInfo;
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
import com.intellij.refactoring.util.CanonicalTypes;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -66,8 +70,11 @@ public class ParameterCanBeLocalInspection extends ParameterCanBeLocalInspection
|
||||
}
|
||||
final ParameterInfoImpl[] newParams = info.toArray(new ParameterInfoImpl[info.size()]);
|
||||
final String visibilityModifier = VisibilityUtil.getVisibilityModifier(method.getModifierList());
|
||||
final ChangeSignatureProcessor cp = new ChangeSignatureProcessor(project, method, false, visibilityModifier,
|
||||
method.getName(), method.getReturnType(), newParams) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final JavaChangeInfo changeInfo = new JavaChangeInfoImpl(visibilityModifier, method, method.getName(),
|
||||
returnType != null ? CanonicalTypes.createTypeWrapper(returnType) : null,
|
||||
newParams, null, false, ContainerUtil.newHashSet(), ContainerUtil.newHashSet());
|
||||
final ChangeSignatureProcessor cp = new ChangeSignatureProcessor(project, changeInfo) {
|
||||
@Override
|
||||
protected void performRefactoring(@NotNull UsageInfo[] usages) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
@@ -1278,8 +1278,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
|
||||
public SyntheticCodeBlock createCodeBlockBlock(final List<Block> localResult, final Indent indent, final int childrenIndent) {
|
||||
final SyntheticCodeBlock result = new SyntheticCodeBlock(localResult, null, getSettings(), myJavaSettings, indent, null);
|
||||
result.setChildAttributes(new ChildAttributes(getCodeBlockInternalIndent(childrenIndent), null));
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -18,13 +18,13 @@ package com.intellij.psi.impl.file;
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Maxim.Mossienko
|
||||
* Date: Sep 18, 2008
|
||||
* Time: 3:33:07 PM
|
||||
* @since Sep 18, 2008
|
||||
*/
|
||||
public class JavaUpdateAddedFileProcessor extends UpdateAddedFileProcessor {
|
||||
@Override
|
||||
@@ -34,14 +34,17 @@ public class JavaUpdateAddedFileProcessor extends UpdateAddedFileProcessor {
|
||||
|
||||
@Override
|
||||
public void update(final PsiFile element, PsiFile originalElement) throws IncorrectOperationException {
|
||||
if (element.getViewProvider() instanceof TemplateLanguageFileViewProvider) return;
|
||||
if (element.getViewProvider() instanceof TemplateLanguageFileViewProvider || PsiUtil.isModuleFile(element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiDirectory dir = element.getContainingDirectory();
|
||||
if (dir == null) return;
|
||||
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(dir);
|
||||
if (aPackage == null) return;
|
||||
String packageName = aPackage.getQualifiedName();
|
||||
|
||||
((PsiClassOwner)element).setPackageName(packageName);
|
||||
if (dir != null) {
|
||||
PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(dir);
|
||||
if (aPackage != null) {
|
||||
String packageName = aPackage.getQualifiedName();
|
||||
((PsiClassOwner)element).setPackageName(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -66,6 +66,9 @@ public class ImportHelper{
|
||||
}
|
||||
|
||||
public PsiImportList prepareOptimizeImportsResult(@NotNull final PsiJavaFile file) {
|
||||
PsiImportList oldList = file.getImportList();
|
||||
if (oldList == null) return null;
|
||||
|
||||
// Java parser works in a way that comments may be included to the import list, e.g.:
|
||||
// import a;
|
||||
// /* comment */
|
||||
@@ -98,8 +101,8 @@ public class ImportHelper{
|
||||
codeStyleManager.reformat(dummyFile);
|
||||
|
||||
PsiImportList newImportList = dummyFile.getImportList();
|
||||
assert newImportList != null : dummyFile.getText();
|
||||
PsiImportList result = (PsiImportList)newImportList.copy();
|
||||
PsiImportList oldList = file.getImportList();
|
||||
if (oldList.isReplaceEquivalent(result)) return null;
|
||||
if (!nonImports.isEmpty()) {
|
||||
PsiElement firstPrevious = newImportList.getPrevSibling();
|
||||
@@ -431,6 +434,7 @@ public class ImportHelper{
|
||||
|
||||
try {
|
||||
PsiImportList importList = file.getImportList();
|
||||
assert importList != null : file;
|
||||
PsiImportStatement statement = useOnDemand ? factory.createImportStatementOnDemand(packageName) : factory.createImportStatement(refClass);
|
||||
importList.add(statement);
|
||||
if (useOnDemand) {
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi.stubsHierarchy.impl;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubsHierarchy.ClassHierarchy;
|
||||
@@ -113,10 +112,6 @@ public class SingleClassHierarchy extends ClassHierarchy {
|
||||
@NotNull
|
||||
@Override
|
||||
public SmartClassAnchor[] getDirectSubtypeCandidates(@NotNull PsiClass psiClass) {
|
||||
PsiElement original = psiClass.getOriginalElement();
|
||||
if (original instanceof PsiClass) {
|
||||
psiClass = (PsiClass)original;
|
||||
}
|
||||
VirtualFile vFile = psiClass.getContainingFile().getVirtualFile();
|
||||
if (!(vFile instanceof VirtualFileWithId)) return StubClassAnchor.EMPTY_ARRAY;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.psi.stubsHierarchy.impl;
|
||||
import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.BitUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -69,7 +70,7 @@ public class StubResolver {
|
||||
private void findType(Symbol startScope, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
// looking up
|
||||
for (Symbol s = startScope; s != null; s = s.myOwner)
|
||||
findMemberType(s, name, symbols, new HashSet<Symbol>());
|
||||
findMemberType(s, name, symbols);
|
||||
// type from current package
|
||||
findIdentInPackage(startScope.pkg(), name, IndexTree.CLASS, symbols);
|
||||
}
|
||||
@@ -79,7 +80,7 @@ public class StubResolver {
|
||||
if (receiver.isPackage())
|
||||
findIdentInPackage((Symbol.PackageSymbol)receiver, name, kind, symbols);
|
||||
else
|
||||
findMemberType(receiver, name, symbols, new HashSet<Symbol>());
|
||||
findMemberType(receiver, name, symbols);
|
||||
}
|
||||
|
||||
private void findIdentInPackage(Symbol.PackageSymbol pck, int name, int kind, Set<Symbol> symbols) {
|
||||
@@ -97,19 +98,34 @@ public class StubResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void findMemberType(Symbol s, int name, Set<Symbol> symbols, Set<Symbol> processed) throws IncompleteHierarchyException {
|
||||
if (!processed.add(s)) {
|
||||
return;
|
||||
private void findMemberType(Symbol s, int name, Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
if (s.isClass()) {
|
||||
processInheritedMembers((Symbol.ClassSymbol)s, name, false, symbols, null);
|
||||
} else {
|
||||
processMembers(s.getMembers(), name, symbols, false);
|
||||
}
|
||||
processMembers(s.getMembers(), name, symbols, false);
|
||||
if (s.isClass())
|
||||
findInheritedMemberType((Symbol.ClassSymbol)s, name, symbols, processed);
|
||||
}
|
||||
|
||||
private void findInheritedMemberType(Symbol.ClassSymbol c, int name, Set<Symbol> symbols, Set<Symbol> processed)
|
||||
throws IncompleteHierarchyException {
|
||||
for (Symbol.ClassSymbol st : c.getSuperClasses(myConnector))
|
||||
findMemberType(st, name, symbols, processed);
|
||||
private void processInheritedMembers(Symbol.ClassSymbol s,
|
||||
int name,
|
||||
boolean requireStatic,
|
||||
Set<Symbol> symbols,
|
||||
@Nullable Set<Symbol> processed) throws IncompleteHierarchyException {
|
||||
processMembers(s.getMembers(), name, symbols, requireStatic);
|
||||
|
||||
@CompactArray(Symbol.ClassSymbol.class) Object supers = s.getSuperClasses(myConnector);
|
||||
if (supers == null) return;
|
||||
|
||||
if (processed == null) processed = new HashSet<>();
|
||||
if (!processed.add(s)) return;
|
||||
|
||||
if (supers instanceof Symbol.ClassSymbol) {
|
||||
processInheritedMembers((Symbol.ClassSymbol)supers, name, requireStatic, symbols, processed);
|
||||
} else if (supers instanceof Symbol.ClassSymbol[]) {
|
||||
for (Symbol.ClassSymbol st : (Symbol.ClassSymbol[])supers) {
|
||||
processInheritedMembers(st, name, requireStatic, symbols, processed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Symbol.ClassSymbol[] loadClass(@NotNull QualifiedName fqn) {
|
||||
@@ -171,16 +187,7 @@ public class StubResolver {
|
||||
|
||||
// handling of import static `tsym.name` as
|
||||
private void importNamedStatic(final Symbol.ClassSymbol tsym, final int name, final Set<Symbol> symbols) throws IncompleteHierarchyException {
|
||||
new Object() {
|
||||
Set<Symbol> processed = new HashSet<Symbol>();
|
||||
void importFrom(Symbol.ClassSymbol cs) throws IncompleteHierarchyException {
|
||||
if (cs == null || !processed.add(cs))
|
||||
return;
|
||||
for (Symbol.ClassSymbol c : cs.getSuperClasses(myConnector))
|
||||
importFrom(c);
|
||||
processMembers(cs.getMembers(), name, symbols, true);
|
||||
}
|
||||
}.importFrom(tsym);
|
||||
processInheritedMembers(tsym, name, true, symbols, null);
|
||||
}
|
||||
|
||||
private static void processMembers(Symbol.ClassSymbol[] members, int name, Set<Symbol> symbols, boolean requireStatic) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.psi.impl.java.stubs.hierarchy.IndexTree;
|
||||
import com.intellij.util.BitUtil;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -125,13 +126,14 @@ public abstract class Symbol {
|
||||
return BitUtil.isSet(myFlags, CONNECT_STARTED);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
ClassSymbol[] getSuperClasses(StubHierarchyConnector connector) throws IncompleteHierarchyException {
|
||||
@Nullable
|
||||
@CompactArray(ClassSymbol.class)
|
||||
Object getSuperClasses(StubHierarchyConnector connector) throws IncompleteHierarchyException {
|
||||
connect(connector);
|
||||
if (isHierarchyIncomplete()) {
|
||||
throw IncompleteHierarchyException.INSTANCE;
|
||||
}
|
||||
return rawSuperClasses();
|
||||
return mySuperClasses;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+6
-2
@@ -118,8 +118,11 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
||||
newVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList());
|
||||
}
|
||||
|
||||
return new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
|
||||
propagateParametersMethods, propagateExceptionsMethods);
|
||||
final JavaChangeInfoImpl javaChangeInfo =
|
||||
new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
|
||||
propagateParametersMethods, propagateExceptionsMethods);
|
||||
javaChangeInfo.setCheckUnusedParameter();
|
||||
return javaChangeInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -151,6 +154,7 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
||||
RenameUtil.removeConflictUsages(usagesSet);
|
||||
if (!conflictDescriptions.isEmpty()) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
if (ConflictsInTestsException.isTestIgnore()) return true;
|
||||
throw new ConflictsInTestsException(conflictDescriptions.values());
|
||||
}
|
||||
if (myPrepareSuccessfulSwingThreadCallback != null) {
|
||||
|
||||
@@ -68,4 +68,9 @@ public interface JavaChangeInfo extends ChangeInfo {
|
||||
void updateMethod(PsiMethod psiMethod);
|
||||
|
||||
Collection<PsiMethod> getMethodsToPropagateParameters();
|
||||
|
||||
default boolean checkUnusedParameter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
final Set<PsiMethod> propagateParametersMethods;
|
||||
final Set<PsiMethod> propagateExceptionsMethods;
|
||||
|
||||
private boolean myCheckUnusedParameter = false;
|
||||
|
||||
/**
|
||||
* @param newExceptions null if not changed
|
||||
*/
|
||||
@@ -201,6 +203,15 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkUnusedParameter() {
|
||||
return myCheckUnusedParameter;
|
||||
}
|
||||
|
||||
public void setCheckUnusedParameter() {
|
||||
myCheckUnusedParameter = true;
|
||||
}
|
||||
|
||||
protected void fillOldParams(PsiMethod method) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
oldParameterNames = new String[parameters.length];
|
||||
|
||||
+35
-9
@@ -24,8 +24,6 @@ import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -34,6 +32,8 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.scope.processor.VariablesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.rename.RenameUtil;
|
||||
@@ -991,7 +991,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
|
||||
public MultiMap<PsiElement, String> findConflicts(Ref<UsageInfo[]> refUsages) {
|
||||
MultiMap<PsiElement, String> conflictDescriptions = new MultiMap<PsiElement, String>();
|
||||
addMethodConflicts(conflictDescriptions);
|
||||
final PsiMethod prototype = addMethodConflicts(conflictDescriptions);
|
||||
Set<UsageInfo> usagesSet = new HashSet<UsageInfo>(Arrays.asList(refUsages.get()));
|
||||
RenameUtil.removeConflictUsages(usagesSet);
|
||||
if (myChangeInfo.isVisibilityChanged()) {
|
||||
@@ -1002,7 +1002,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final boolean[] toRemove = myChangeInfo.toRemoveParm();
|
||||
//introduce parameter object deletes parameters but replaces their usages with generated code
|
||||
final boolean checkUnusedParameter = myChangeInfo.checkUnusedParameter();
|
||||
if (checkUnusedParameter) {
|
||||
checkParametersToDelete(myChangeInfo.getMethod(), toRemove, conflictDescriptions);
|
||||
}
|
||||
checkContract(conflictDescriptions, myChangeInfo.getMethod());
|
||||
|
||||
for (UsageInfo usageInfo : usagesSet) {
|
||||
@@ -1012,11 +1018,16 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
final PsiMethod baseMethod = ((OverriderUsageInfo)usageInfo).getBaseMethod();
|
||||
final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount();
|
||||
if (delta > 0) {
|
||||
final boolean[] toRemove = myChangeInfo.toRemoveParm();
|
||||
if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one
|
||||
conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted");
|
||||
}
|
||||
}
|
||||
else if (prototype != null && baseMethod == myChangeInfo.getMethod()) {
|
||||
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflictDescriptions);
|
||||
if (checkUnusedParameter) {
|
||||
checkParametersToDelete(method, toRemove, conflictDescriptions);
|
||||
}
|
||||
}
|
||||
|
||||
checkContract(conflictDescriptions, method);
|
||||
}
|
||||
@@ -1028,6 +1039,19 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
return conflictDescriptions;
|
||||
}
|
||||
|
||||
private static void checkParametersToDelete(PsiMethod method, boolean[] toRemove, MultiMap<PsiElement, String> conflictDescriptions) {
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body != null) {
|
||||
final LocalSearchScope searchScope = new LocalSearchScope(body);
|
||||
for (int i = 0; i < toRemove.length; i++) {
|
||||
if (toRemove[i] && ReferencesSearch.search(parameters[i], searchScope).findFirst() != null) {
|
||||
conflictDescriptions.putValue(parameters[i], StringUtil.capitalize(RefactoringUIUtil.getDescription(parameters[i], true)) + " is used in method body");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkContract(MultiMap<PsiElement, String> conflictDescriptions, PsiMethod method) {
|
||||
PsiAnnotation contract = ControlFlowAnalyzer.findContractAnnotation(method);
|
||||
if (contract != null && !AnnotationUtil.isInferredAnnotation(contract)) {
|
||||
@@ -1075,15 +1099,15 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
|
||||
private void addMethodConflicts(MultiMap<PsiElement, String> conflicts) {
|
||||
private PsiMethod addMethodConflicts(MultiMap<PsiElement, String> conflicts) {
|
||||
String newMethodName = myChangeInfo.getNewName();
|
||||
try {
|
||||
PsiMethod prototype;
|
||||
final PsiMethod method = myChangeInfo.getMethod();
|
||||
if (!StdLanguages.JAVA.equals(method.getLanguage())) return;
|
||||
if (!StdLanguages.JAVA.equals(method.getLanguage())) return null;
|
||||
PsiManager manager = method.getManager();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType();
|
||||
PsiMethod prototype;
|
||||
if (returnType != null) {
|
||||
prototype = factory.createMethod(newMethodName, returnType.getType(method, manager));
|
||||
}
|
||||
@@ -1104,11 +1128,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
prototype.getParameterList().add(param);
|
||||
}
|
||||
|
||||
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflicts);
|
||||
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), myChangeInfo.isGenerateDelegate() ? null : method, prototype, conflicts);
|
||||
return prototype;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.TargetElementUtil;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -27,6 +28,7 @@ import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -77,38 +79,43 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
|
||||
|
||||
final String localName = local.getName();
|
||||
|
||||
final Query<PsiReference> query = ReferencesSearch.search(local, local.getUseScope());
|
||||
if (query.findFirst() == null){
|
||||
LOG.assertTrue(refExpr == null);
|
||||
String message = RefactoringBundle.message("variable.is.never.used", localName);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class);
|
||||
final List<PsiElement> innerClassesWithUsages = Collections.synchronizedList(new ArrayList<PsiElement>());
|
||||
final List<PsiElement> innerClassUsages = Collections.synchronizedList(new ArrayList<PsiElement>());
|
||||
query.forEach(psiReference -> {
|
||||
final PsiElement element = psiReference.getElement();
|
||||
PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class);
|
||||
while (innerClass != containingClass && innerClass != null) {
|
||||
final PsiClass parentPsiClass = PsiTreeUtil.getParentOfType(innerClass, PsiClass.class, true);
|
||||
if (parentPsiClass == containingClass) {
|
||||
if (innerClass instanceof PsiLambdaExpression) {
|
||||
if (PsiTreeUtil.isAncestor(innerClass, local, false)) {
|
||||
innerClassesWithUsages.add(element);
|
||||
innerClass = parentPsiClass;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
innerClassesWithUsages.add(innerClass);
|
||||
innerClassUsages.add(element);
|
||||
}
|
||||
innerClass = parentPsiClass;
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class);
|
||||
final Query<PsiReference> query = ReferencesSearch.search(local, local.getUseScope());
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
|
||||
if (query.findFirst() == null){
|
||||
LOG.assertTrue(refExpr == null);
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
String message = RefactoringBundle.message("variable.is.never.used", localName);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
|
||||
}, ModalityState.NON_MODAL);
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
query.forEach(psiReference -> {
|
||||
final PsiElement element = psiReference.getElement();
|
||||
PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class);
|
||||
while (innerClass != containingClass && innerClass != null) {
|
||||
final PsiClass parentPsiClass = PsiTreeUtil.getParentOfType(innerClass, PsiClass.class, true);
|
||||
if (parentPsiClass == containingClass) {
|
||||
if (innerClass instanceof PsiLambdaExpression) {
|
||||
if (PsiTreeUtil.isAncestor(innerClass, local, false)) {
|
||||
innerClassesWithUsages.add(element);
|
||||
innerClass = parentPsiClass;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
innerClassesWithUsages.add(innerClass);
|
||||
innerClassUsages.add(element);
|
||||
}
|
||||
innerClass = parentPsiClass;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
}, "Find Usages", true, project)) {
|
||||
return;
|
||||
}
|
||||
final PsiCodeBlock containerBlock = PsiTreeUtil.getParentOfType(local, PsiCodeBlock.class);
|
||||
if (containerBlock == null) {
|
||||
final String message = RefactoringBundle.getCannotRefactorMessage("Variable is declared outside a code block");
|
||||
@@ -116,9 +123,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiExpression defToInline = innerClassesWithUsages.isEmpty()
|
||||
? getDefToInline(local, refExpr, containerBlock)
|
||||
: getDefToInline(local, innerClassesWithUsages.get(0), containerBlock);
|
||||
final PsiExpression defToInline = getDefToInline(local, innerClassesWithUsages.isEmpty() ? refExpr : innerClassesWithUsages.get(0), containerBlock);
|
||||
if (defToInline == null){
|
||||
final String key = refExpr == null ? "variable.has.no.initializer" : "variable.has.no.dominating.definition";
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName));
|
||||
@@ -150,7 +155,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
|
||||
if (refExpr != null && inlineLocalDialog.isInlineThis()) {
|
||||
refsToInlineList = Collections.<PsiElement>singletonList(refExpr);
|
||||
refsToInlineList = Collections.singletonList(refExpr);
|
||||
inlineAll.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-29
@@ -353,14 +353,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
try {
|
||||
text = file.getText().subSequence(startOffset, endOffset).toString();
|
||||
String prefix = null;
|
||||
String stripped = text;
|
||||
if (startLiteralExpression != null) {
|
||||
final int startExpressionOffset = startLiteralExpression.getTextOffset();
|
||||
if (startOffset == startExpressionOffset) {
|
||||
if (StringUtil.startsWithChar(text, '\"') || StringUtil.startsWithChar(text, '\'')) {
|
||||
stripped = text.substring(1);
|
||||
}
|
||||
} else if (startOffset == startExpressionOffset + 1) {
|
||||
if (startOffset == startExpressionOffset + 1) {
|
||||
text = "\"" + text;
|
||||
} else if (startOffset > startExpressionOffset + 1){
|
||||
prefix = "\" + ";
|
||||
@@ -371,11 +366,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
String suffix = null;
|
||||
if (endLiteralExpression != null) {
|
||||
final int endExpressionOffset = endLiteralExpression.getTextOffset() + endLiteralExpression.getTextLength();
|
||||
if (endOffset == endExpressionOffset ) {
|
||||
if (StringUtil.endsWithChar(stripped, '\"') || StringUtil.endsWithChar(stripped, '\'')) {
|
||||
stripped = stripped.substring(0, stripped.length() - 1);
|
||||
}
|
||||
} else if (endOffset == endExpressionOffset - 1) {
|
||||
if (endOffset == endExpressionOffset - 1) {
|
||||
text += "\"";
|
||||
} else if (endOffset < endExpressionOffset - 1) {
|
||||
suffix = " + \"";
|
||||
@@ -383,24 +374,6 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
}
|
||||
}
|
||||
|
||||
boolean primitive = false;
|
||||
if (stripped.equals("true") || stripped.equals("false")) {
|
||||
primitive = true;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Integer.parseInt(stripped);
|
||||
primitive = true;
|
||||
}
|
||||
catch (NumberFormatException e1) {
|
||||
//then not primitive
|
||||
}
|
||||
}
|
||||
|
||||
if (primitive) {
|
||||
text = stripped;
|
||||
}
|
||||
|
||||
if (literalExpression != null && text.equals(literalExpression.getText())) return literalExpression;
|
||||
|
||||
final PsiElement parent = literalExpression != null ? literalExpression : elementAt;
|
||||
|
||||
+6
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -26,13 +26,13 @@ import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.FileTypeUtils;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.MoveDestination;
|
||||
import com.intellij.refactoring.PackageWrapper;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
|
||||
@@ -40,7 +40,6 @@ import com.intellij.refactoring.util.MoveRenameUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.TextOccurrencesUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -236,16 +235,15 @@ public class MoveClassesOrPackagesUtil {
|
||||
final PsiDirectory containingDirectory = file.getContainingDirectory();
|
||||
if (!Comparing.equal(moveDestination.getVirtualFile(), containingDirectory != null ? containingDirectory.getVirtualFile() : null)) {
|
||||
LOG.assertTrue(file.getVirtualFile() != null, aClass);
|
||||
|
||||
MoveFilesOrDirectoriesUtil.doMoveFile(file, moveDestination);
|
||||
if (file instanceof PsiClassOwner && newPackage != null && !FileTypeUtils.isInServerPageFile(file)) {
|
||||
|
||||
if (newPackage != null && file instanceof PsiClassOwner && !FileTypeUtils.isInServerPageFile(file) && !PsiUtil.isModuleFile(file)) {
|
||||
// Do not rely on class instance identity retention after setPackageName (Scala)
|
||||
String aClassName = aClass.getName();
|
||||
((PsiClassOwner)file).setPackageName(newPackage.getQualifiedName());
|
||||
newClass = findClassByName((PsiClassOwner)file, aClassName);
|
||||
LOG.assertTrue(newClass != null, "name: " + aClassName +
|
||||
", file: " + file +
|
||||
", classes: " + StringUtil.join(((PsiClassOwner)file).getClasses(),
|
||||
psiClass -> psiClass.getName(), " "));
|
||||
LOG.assertTrue(newClass != null, "name:" + aClassName + " file:" + file + " classes:" + Arrays.toString(((PsiClassOwner)file).getClasses()));
|
||||
}
|
||||
}
|
||||
return newClass;
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ConflictsUtil {
|
||||
}
|
||||
|
||||
public static void checkMethodConflicts(@Nullable PsiClass aClass,
|
||||
PsiMethod refactoredMethod,
|
||||
@Nullable PsiMethod refactoredMethod,
|
||||
final PsiMethod prototype,
|
||||
final MultiMap<PsiElement,String> conflicts) {
|
||||
if (prototype == null) return;
|
||||
|
||||
-1
@@ -32,7 +32,6 @@ import com.intellij.util.QueryExecutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FunctionalExpressionSearch extends ExtensibleQueryFactory<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
|
||||
public static final ExtensionPointName<QueryExecutor> EP_NAME = ExtensionPointName.create("com.intellij.functionalInterfaceSearch");
|
||||
public static final FunctionalExpressionSearch INSTANCE = new FunctionalExpressionSearch();
|
||||
|
||||
public static class SearchParameters {
|
||||
|
||||
+6
-11
@@ -19,7 +19,6 @@ import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFunctionalExpression;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
@@ -37,20 +36,16 @@ public class ClassImplementationsSearch implements QueryExecutor<PsiElement, Def
|
||||
}
|
||||
|
||||
public static boolean processImplementations(final PsiClass psiClass, final Processor<PsiElement> processor, SearchScope scope) {
|
||||
if (!FunctionalExpressionSearch.search(psiClass, scope).forEach(expression -> {
|
||||
return processor.process(expression);
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces");
|
||||
return ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
|
||||
public boolean execute(@NotNull PsiClass element) {
|
||||
if (!ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(element -> {
|
||||
if (!showInterfaces && element.isInterface()) {
|
||||
return true;
|
||||
}
|
||||
return processor.process(element);
|
||||
}
|
||||
}));
|
||||
}))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return FunctionalExpressionSearch.search(psiClass, scope).forEach((Processor<PsiFunctionalExpression>)processor::process);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -59,14 +59,14 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
|
||||
private static boolean processAllClassesInGlobalScope(@NotNull final GlobalSearchScope scope,
|
||||
@NotNull final AllClassesSearch.SearchParameters parameters,
|
||||
@NotNull Processor<PsiClass> processor) {
|
||||
final Set<String> names = new THashSet<String>(10000);
|
||||
final Set<String> names = new THashSet<>(10000);
|
||||
processClassNames(parameters.getProject(), scope, s -> {
|
||||
if (parameters.nameMatches(s)) {
|
||||
names.add(s);
|
||||
}
|
||||
});
|
||||
|
||||
List<String> sorted = new ArrayList<String>(names);
|
||||
List<String> sorted = new ArrayList<>(names);
|
||||
Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
return processClassesByNames(parameters.getProject(), scope, sorted, processor);
|
||||
|
||||
+12
-9
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
|
||||
@@ -26,9 +27,9 @@ import com.intellij.psi.search.searches.AnnotatedElementsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -39,15 +40,15 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
|
||||
@Override
|
||||
public boolean execute(@NotNull final AnnotatedElementsSearch.Parameters p, @NotNull final Processor<PsiModifierListOwner> consumer) {
|
||||
final PsiClass annClass = p.getAnnotationClass();
|
||||
assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search";
|
||||
if (!annClass.isAnnotationType()) throw new IllegalArgumentException("Annotation type should be passed to annotated members search but got: "+annClass);
|
||||
|
||||
final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return annClass.getQualifiedName();
|
||||
}
|
||||
});
|
||||
assert annotationFQN != null;
|
||||
if (annotationFQN == null) throw new IllegalArgumentException("FQN is null for "+annClass);
|
||||
|
||||
final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable<PsiManager>() {
|
||||
@Override
|
||||
@@ -59,7 +60,7 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
|
||||
final SearchScope useScope = p.getScope();
|
||||
final Class<? extends PsiModifierListOwner>[] types = p.getTypes();
|
||||
|
||||
for (final PsiAnnotation ann : getAnnotationCandidates(annClass, useScope)) {
|
||||
for (final PsiAnnotation ann : getAnnotationCandidates(annClass, useScope, psiManager.getProject())) {
|
||||
final PsiModifierListOwner candidate = ApplicationManager.getApplication().runReadAction(new Computable<PsiModifierListOwner>() {
|
||||
@Override
|
||||
public PsiModifierListOwner compute() {
|
||||
@@ -90,15 +91,17 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Collection<PsiAnnotation> getAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) {
|
||||
@NotNull
|
||||
private static Collection<PsiAnnotation> getAnnotationCandidates(@NotNull PsiClass annClass,
|
||||
@NotNull SearchScope useScope, @NotNull Project project) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiAnnotation>>() {
|
||||
@Override
|
||||
public Collection<PsiAnnotation> compute() {
|
||||
if (useScope instanceof GlobalSearchScope) {
|
||||
return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope)useScope);
|
||||
return JavaAnnotationIndex.getInstance().get(annClass.getName(), project, (GlobalSearchScope)useScope);
|
||||
}
|
||||
|
||||
final List<PsiAnnotation> result = ContainerUtil.newArrayList();
|
||||
List<PsiAnnotation> result = new ArrayList<>();
|
||||
for (PsiElement element : ((LocalSearchScope)useScope).getScope()) {
|
||||
result.addAll(PsiTreeUtil.findChildrenOfType(element, PsiAnnotation.class));
|
||||
}
|
||||
@@ -107,7 +110,7 @@ public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListO
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean isInstanceof(PsiElement owner, Class<? extends PsiModifierListOwner>[] types) {
|
||||
public static boolean isInstanceof(PsiElement owner, @NotNull Class<? extends PsiModifierListOwner>[] types) {
|
||||
for (Class<? extends PsiModifierListOwner> type : types) {
|
||||
if(type.isInstance(owner)) return true;
|
||||
}
|
||||
|
||||
+3
-3
@@ -75,9 +75,9 @@ public class AnnotatedPackagesSearcher implements QueryExecutor<PsiPackage, Anno
|
||||
boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>(){
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
PsiModifierList modlist = (PsiModifierList)annotation.getParent();
|
||||
final PsiElement owner = modlist.getParent();
|
||||
if ((owner instanceof PsiClass)) {
|
||||
PsiModifierList modList = (PsiModifierList)annotation.getParent();
|
||||
final PsiElement owner = modList.getParent();
|
||||
if (owner instanceof PsiClass) {
|
||||
PsiClass candidate = (PsiClass)owner;
|
||||
if ("package-info".equals(candidate.getName())) {
|
||||
LOG.assertTrue(candidate.isValid());
|
||||
|
||||
+4
-3
@@ -15,10 +15,11 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.QueryExecutorBase;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch;
|
||||
@@ -45,7 +46,7 @@ public class ClassesWithAnnotatedMembersSearcher extends QueryExecutorBase<PsiCl
|
||||
}
|
||||
}
|
||||
|
||||
final Set<PsiClass> processed = new HashSet<PsiClass>();
|
||||
final Set<PsiClass> processed = new HashSet<>();
|
||||
AnnotatedElementsSearch.searchPsiMembers(queryParameters.getAnnotationClass(), scope).forEach(member -> {
|
||||
PsiClass psiClass;
|
||||
AccessToken token = ReadAction.start();
|
||||
|
||||
+10
-10
@@ -35,10 +35,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class ConstructorReferencesSearchHelper {
|
||||
class ConstructorReferencesSearchHelper {
|
||||
private final PsiManager myManager;
|
||||
|
||||
public ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
|
||||
ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
|
||||
myManager = manager;
|
||||
}
|
||||
|
||||
@@ -48,14 +48,14 @@ public class ConstructorReferencesSearchHelper {
|
||||
* 2. Exception avoidance. Project is needed outside of read action (to run it via DumbService in the first place),
|
||||
* and so getProject would fail with an assertion that read action is required but not present.
|
||||
*/
|
||||
public boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
|
||||
@NotNull final PsiMethod constructor,
|
||||
@NotNull final PsiClass containingClass,
|
||||
@NotNull final SearchScope searchScope,
|
||||
@NotNull final Project project,
|
||||
boolean ignoreAccessScope,
|
||||
final boolean isStrictSignatureSearch,
|
||||
@NotNull SearchRequestCollector collector) {
|
||||
boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
|
||||
@NotNull final PsiMethod constructor,
|
||||
@NotNull final PsiClass containingClass,
|
||||
@NotNull final SearchScope searchScope,
|
||||
@NotNull final Project project,
|
||||
boolean ignoreAccessScope,
|
||||
final boolean isStrictSignatureSearch,
|
||||
@NotNull SearchRequestCollector collector) {
|
||||
final boolean[] constructorCanBeCalledImplicitly = new boolean[1];
|
||||
final boolean[] isEnum = new boolean[1];
|
||||
final boolean[] isUnder18 = new boolean[1];
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReferenc
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
final PsiManager[] manager = new PsiManager[1];
|
||||
PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
|
||||
@Override
|
||||
public PsiClass compute() {
|
||||
if (!method.isConstructor()) return null;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
|
||||
+22
-23
@@ -29,7 +29,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaAnonymousClassBaseRefOccurenceIndex;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaSuperClassNameOccurenceIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScopeUtil;
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.AllClassesSearch;
|
||||
@@ -43,9 +43,11 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -82,7 +84,8 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
int groupStart = 0;
|
||||
boolean sameJarClassFound = false;
|
||||
String currentFQN = null;
|
||||
for (int i = 0; i < cache.length +1; i++) {
|
||||
boolean[] isOutOfScope = new boolean[cache.length]; // here we cache results of isInScope(scope, subClass) to avoid calculating it twice
|
||||
for (int i = 0; i <= cache.length; i++) {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
PsiClass subClass = i == cache.length ? null : cache[i];
|
||||
@@ -92,9 +95,12 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (i != cache.length && !isInScope(scope, subClass)) {
|
||||
isOutOfScope[i] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
String fqn = i == cache.length ? null : ApplicationManager.getApplication().runReadAction((Computable<String>)subClass::getQualifiedName);
|
||||
if (i != cache.length && !isInScope(scope, subClass)) continue;
|
||||
|
||||
if (currentFQN != null && Comparing.equal(fqn, currentFQN)) {
|
||||
VirtualFile currentJarFile = getJarFile(subClass);
|
||||
@@ -113,8 +119,9 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
if (!sameJarClassFound) {
|
||||
for (int g=groupStart; g<i; g++) {
|
||||
ProgressManager.checkCanceled();
|
||||
PsiClass anonSubClass = cache[g];
|
||||
if (!consumer.process(anonSubClass)) return false;
|
||||
if (isOutOfScope[g]) continue;
|
||||
PsiClass subClassCandidate = cache[g];
|
||||
if (!consumer.process(subClassCandidate)) return false;
|
||||
}
|
||||
}
|
||||
groupStart = i;
|
||||
@@ -162,27 +169,19 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
return ContainerUtil.process(collection, processor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static GlobalSearchScope toGlobal(@NotNull final SearchScope scope, @NotNull Project project) {
|
||||
if (scope instanceof GlobalSearchScope) {
|
||||
return (GlobalSearchScope)scope;
|
||||
}
|
||||
Set<VirtualFile> files = Arrays.stream(((LocalSearchScope)scope).getScope()).map(PsiUtil::getVirtualFile).collect(Collectors.toSet());
|
||||
return GlobalSearchScope.filesScope(project, files);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiClass[] calculateDirectSubClasses(@NotNull Project project,
|
||||
@NotNull PsiClass baseClass,
|
||||
@NotNull String baseClassName,
|
||||
@NotNull SearchScope useScope) {
|
||||
DumbService dumbService = DumbService.getInstance(project);
|
||||
GlobalSearchScope globalUseScope = dumbService.runReadActionInSmartMode(() -> StubHierarchyInheritorSearcher.restrictScope(toGlobal(useScope, project)));
|
||||
GlobalSearchScope globalUseScope = dumbService.runReadActionInSmartMode(
|
||||
() -> StubHierarchyInheritorSearcher.restrictScope(GlobalSearchScopeUtil.toGlobalSearchScope(useScope, project)));
|
||||
Collection<PsiReferenceList> candidates =
|
||||
dumbService.runReadActionInSmartMode(() -> JavaSuperClassNameOccurenceIndex.getInstance().get(baseClassName, project, globalUseScope));
|
||||
|
||||
// memory/speed optimisation: it really is a map(string -> PsiClass or List<PsiClass>)
|
||||
final Map<String, Object> classes = new HashMap<>();
|
||||
final Map<String, Object> classesWithFqn = new HashMap<>();
|
||||
|
||||
processConcurrentlyIfTooMany(candidates,
|
||||
referenceList -> {
|
||||
@@ -192,16 +191,16 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
boolean isInheritor = candidate.isInheritor(baseClass, false);
|
||||
if (isInheritor) {
|
||||
String fqn = candidate.getQualifiedName();
|
||||
synchronized (classes) {
|
||||
Object value = classes.get(fqn);
|
||||
synchronized (classesWithFqn) {
|
||||
Object value = classesWithFqn.get(fqn);
|
||||
if (value == null) {
|
||||
classes.put(fqn, candidate);
|
||||
classesWithFqn.put(fqn, candidate);
|
||||
}
|
||||
else if (value instanceof PsiClass) {
|
||||
List<PsiClass> list = new ArrayList<>();
|
||||
list.add((PsiClass)value);
|
||||
list.add(candidate);
|
||||
classes.put(fqn, list);
|
||||
classesWithFqn.put(fqn, list);
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -216,7 +215,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
});
|
||||
|
||||
final List<PsiClass> result = new ArrayList<>();
|
||||
for (Object value : classes.values()) {
|
||||
for (Object value : classesWithFqn.values()) {
|
||||
if (value instanceof PsiClass) {
|
||||
result.add((PsiClass)value);
|
||||
}
|
||||
|
||||
+67
-71
@@ -34,7 +34,7 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<String, Collection<JavaFunctionalExpressionIndex.IndexHolder>> implements PsiDependentIndex {
|
||||
public static final ID<String, Collection<IndexHolder>> JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID = ID.create("java.functional.expression");
|
||||
static final ID<String, Collection<IndexHolder>> JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID = ID.create("java.functional.expression");
|
||||
private static final String THIS_REF_NAME = "this";
|
||||
private static final String SUPER_REF_NAME = "super";
|
||||
|
||||
@@ -47,84 +47,80 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Strin
|
||||
@NotNull
|
||||
@Override
|
||||
public DataIndexer<String, Collection<IndexHolder>, FileContent> getIndexer() {
|
||||
return new DataIndexer<String, Collection<IndexHolder>, FileContent>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Collection<IndexHolder>> map(@NotNull FileContent inputData) {
|
||||
if (!JavaStubElementTypes.JAVA_FILE.shouldBuildStubFor(inputData.getFile())) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final CharSequence contentAsText = inputData.getContentAsText();
|
||||
if (!StringUtil.contains(contentAsText, "::") && !StringUtil.contains(contentAsText, "->")) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return inputData -> {
|
||||
if (!JavaStubElementTypes.JAVA_FILE.shouldBuildStubFor(inputData.getFile())) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final CharSequence contentAsText = inputData.getContentAsText();
|
||||
if (!StringUtil.contains(contentAsText, "::") && !StringUtil.contains(contentAsText, "->")) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final PsiFile file = ((FileContentImpl)inputData).getPsiFileForPsiDependentIndex();
|
||||
if (!(file instanceof PsiJavaFile)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final PsiFile file = ((FileContentImpl)inputData).getPsiFileForPsiDependentIndex();
|
||||
if (!(file instanceof PsiJavaFile)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final HashMap<String, Collection<IndexHolder>> methodsMap = ContainerUtil.newHashMap();
|
||||
for (PsiFunctionalExpression expression : SyntaxTraverser.psiTraverser().withRoot(file).filter(PsiFunctionalExpression.class)) {
|
||||
final PsiExpressionList expressionList =
|
||||
PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class, true, PsiStatement.class, PsiModifierListOwner.class);
|
||||
if (expressionList != null) {
|
||||
final PsiElement parent = expressionList.getParent();
|
||||
String methodName = null;
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
methodName = ((PsiMethodCallExpression)parent).getMethodExpression().getReferenceName();
|
||||
if (methodName != null) {
|
||||
final boolean thisRef = methodName.equals(THIS_REF_NAME);
|
||||
if (thisRef || methodName.equals(SUPER_REF_NAME)) {
|
||||
methodName = null;
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class);
|
||||
if (containingClass != null) {
|
||||
if (thisRef) {
|
||||
methodName = containingClass.getName();
|
||||
} else {
|
||||
final PsiReferenceList extendsList = containingClass.getExtendsList();
|
||||
if (extendsList != null) {
|
||||
final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
|
||||
if (referenceElements.length > 0) {
|
||||
methodName = referenceElements[0].getReferenceName();
|
||||
}
|
||||
final HashMap<String, Collection<IndexHolder>> methodsMap = ContainerUtil.newHashMap();
|
||||
for (PsiFunctionalExpression expression : SyntaxTraverser.psiTraverser().withRoot(file).filter(PsiFunctionalExpression.class)) {
|
||||
final PsiExpressionList expressionList =
|
||||
PsiTreeUtil.getParentOfType(expression, PsiExpressionList.class, true, PsiStatement.class, PsiModifierListOwner.class);
|
||||
if (expressionList != null) {
|
||||
final PsiElement parent = expressionList.getParent();
|
||||
String methodName = null;
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
methodName = ((PsiMethodCallExpression)parent).getMethodExpression().getReferenceName();
|
||||
if (methodName != null) {
|
||||
final boolean thisRef = methodName.equals(THIS_REF_NAME);
|
||||
if (thisRef || methodName.equals(SUPER_REF_NAME)) {
|
||||
methodName = null;
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(parent, PsiClass.class);
|
||||
if (containingClass != null) {
|
||||
if (thisRef) {
|
||||
methodName = containingClass.getName();
|
||||
} else {
|
||||
final PsiReferenceList extendsList = containingClass.getExtendsList();
|
||||
if (extendsList != null) {
|
||||
final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
|
||||
if (referenceElements.length > 0) {
|
||||
methodName = referenceElements[0].getReferenceName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
methodName = classReference.getReferenceName();
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiEnumConstant) {
|
||||
final PsiClass containingClass = ((PsiEnumConstant)parent).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final String shortEnumName = containingClass.getName();
|
||||
if (shortEnumName != null) { //should be always true as enums can't be local
|
||||
methodName = shortEnumName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parent instanceof PsiNewExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
methodName = classReference.getReferenceName();
|
||||
}
|
||||
|
||||
if (methodName != null) {
|
||||
Collection<IndexHolder> holders = methodsMap.get(methodName);
|
||||
if (holders == null) {
|
||||
holders = new HashSet<IndexHolder>();
|
||||
methodsMap.put(methodName, holders);
|
||||
}
|
||||
else if (parent instanceof PsiEnumConstant) {
|
||||
final PsiClass containingClass = ((PsiEnumConstant)parent).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final String shortEnumName = containingClass.getName();
|
||||
if (shortEnumName != null) { //should be always true as enums can't be local
|
||||
methodName = shortEnumName;
|
||||
}
|
||||
holders.add(new IndexHolder(expression instanceof PsiLambdaExpression ? ((PsiLambdaExpression)expression).getParameterList().getParametersCount() : -1,
|
||||
expressionList.getExpressions().length,
|
||||
LambdaUtil.getLambdaIdx(expressionList, expression)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return methodsMap;
|
||||
if (methodName != null) {
|
||||
Collection<IndexHolder> holders = methodsMap.get(methodName);
|
||||
if (holders == null) {
|
||||
holders = new HashSet<>();
|
||||
methodsMap.put(methodName, holders);
|
||||
}
|
||||
holders.add(new IndexHolder(expression instanceof PsiLambdaExpression ? ((PsiLambdaExpression)expression).getParameterList().getParametersCount() : -1,
|
||||
expressionList.getExpressions().length,
|
||||
LambdaUtil.getLambdaIdx(expressionList, expression)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return methodsMap;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -151,7 +147,7 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Strin
|
||||
@Override
|
||||
public Collection<IndexHolder> read(@NotNull DataInput in) throws IOException {
|
||||
int l = DataInputOutputUtil.readINT(in);
|
||||
final Collection<IndexHolder> holders = new HashSet<IndexHolder>(l);
|
||||
final Collection<IndexHolder> holders = new HashSet<>(l);
|
||||
while (l-- > 0) {
|
||||
holders.add(new IndexHolder(DataInputOutputUtil.readINT(in),
|
||||
DataInputOutputUtil.readINT(in),
|
||||
@@ -178,26 +174,26 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Strin
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static class IndexHolder {
|
||||
static class IndexHolder {
|
||||
private final int myLambdaParamsNumber;
|
||||
private final int myMethodArgsLength;
|
||||
private final int myFunctionExpressionIndex;
|
||||
|
||||
public IndexHolder(int lambdaParamsNumber, int methodArgsLength, int functionExpressionIndex) {
|
||||
IndexHolder(int lambdaParamsNumber, int methodArgsLength, int functionExpressionIndex) {
|
||||
myLambdaParamsNumber = lambdaParamsNumber;
|
||||
myMethodArgsLength = methodArgsLength;
|
||||
myFunctionExpressionIndex = functionExpressionIndex;
|
||||
}
|
||||
|
||||
public int getLambdaParamsNumber() {
|
||||
int getLambdaParamsNumber() {
|
||||
return myLambdaParamsNumber;
|
||||
}
|
||||
|
||||
public int getMethodArgsLength() {
|
||||
int getMethodArgsLength() {
|
||||
return myMethodArgsLength;
|
||||
}
|
||||
|
||||
public int getFunctionExpressionIndex() {
|
||||
int getFunctionExpressionIndex() {
|
||||
return myFunctionExpressionIndex;
|
||||
}
|
||||
|
||||
|
||||
+24
-26
@@ -40,15 +40,13 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.Processors;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.util.containers.ContainerUtil.*;
|
||||
import static com.intellij.util.containers.ContainerUtilRt.newHashSet;
|
||||
|
||||
public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
|
||||
private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName());
|
||||
/**
|
||||
@@ -98,7 +96,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
//collect all methods with parameter of functional interface or free type parameter type
|
||||
final Collection<PsiMethod> methodCandidates = getCandidateMethodsWithSuitableParams(aClass, project, useScope, candidateFiles, candidateScope);
|
||||
|
||||
final LinkedHashSet<VirtualFile> filesToProcess = new LinkedHashSet<VirtualFile>();
|
||||
final Set<VirtualFile> filesToProcess = new LinkedHashSet<>();
|
||||
final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance();
|
||||
|
||||
//find all usages of method candidates in files with functional expressions
|
||||
@@ -109,7 +107,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
final boolean varArgs = psiMethod.isVarArgs();
|
||||
final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
|
||||
final GlobalSearchScope methodUseScope = convertToGlobalScope(project, psiMethod.getUseScope());
|
||||
final LinkedHashMap<VirtualFile, Set<JavaFunctionalExpressionIndex.IndexHolder>> holders = new LinkedHashMap<VirtualFile, Set<JavaFunctionalExpressionIndex.IndexHolder>>();
|
||||
final LinkedHashMap<VirtualFile, Set<JavaFunctionalExpressionIndex.IndexHolder>> holders = new LinkedHashMap<>();
|
||||
//functional expressions checker: number and type of parameters at call site should correspond to candidate method currently check
|
||||
final SuitableFilesProcessor processor = new SuitableFilesProcessor(holders, expectedFunExprParamsCount, parametersCount, varArgs, parameters);
|
||||
fileBasedIndex.processValues(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, psiMethod.getName(), null, processor, useScope.intersectWith(methodUseScope));
|
||||
@@ -134,7 +132,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
private static Set<Module> getJava8Modules(Project project) {
|
||||
final boolean projectLevelIsHigh = PsiUtil.getLanguageLevel(project).isAtLeast(LanguageLevel.JDK_1_8);
|
||||
|
||||
final Set<Module> highLevelModules = new HashSet<Module>();
|
||||
final Set<Module> highLevelModules = new HashSet<>();
|
||||
for (Module module : ModuleManager.getInstance(project).getModules()) {
|
||||
final LanguageLevelModuleExtension extension = ModuleRootManager.getInstance(module).getModuleExtension(LanguageLevelModuleExtension.class);
|
||||
if (extension != null) {
|
||||
@@ -151,7 +149,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
final Processor<PsiFunctionalExpression> consumer,
|
||||
Set<VirtualFile> filesToProcess, final int expectedFunExprParamsCount, boolean isVoid) {
|
||||
LOG.info("#usage files: " + filesToProcess.size());
|
||||
process(filesToProcess, new ReadActionProcessor<VirtualFile>() {
|
||||
ContainerUtil.process(filesToProcess, new ReadActionProcessor<VirtualFile>() {
|
||||
@Override
|
||||
public boolean processInReadAction(VirtualFile file) {
|
||||
//resolve functional expressions to ensure that functional expression type is appropriate
|
||||
@@ -172,11 +170,11 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
|
||||
GlobalSearchScope visibleFromCandidates = combineResolveScopes(project, candidateFiles);
|
||||
|
||||
final Set<String> usedMethodNames = newHashSet();
|
||||
Set<String> usedMethodNames = new HashSet<>();
|
||||
FileBasedIndex.getInstance().processAllKeys(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID,
|
||||
Processors.cancelableCollectProcessor(usedMethodNames), candidateScope, null);
|
||||
|
||||
final LinkedHashSet<PsiMethod> methods = newLinkedHashSet();
|
||||
Set<PsiMethod> methods = ContainerUtil.newLinkedHashSet();
|
||||
Processor<PsiMethod> methodProcessor = method -> {
|
||||
if (usedMethodNames.contains(method.getName())) {
|
||||
methods.add(method);
|
||||
@@ -197,7 +195,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
@NotNull
|
||||
private static GlobalSearchScope combineResolveScopes(Project project, Set<VirtualFile> candidateFiles) {
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
Set<GlobalSearchScope> resolveScopes = newLinkedHashSet(mapNotNull(candidateFiles, file -> {
|
||||
Set<GlobalSearchScope> resolveScopes = ContainerUtil.newLinkedHashSet(ContainerUtil.mapNotNull(candidateFiles, file -> {
|
||||
PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null;
|
||||
return psiFile == null ? null : psiFile.getResolveScope();
|
||||
}));
|
||||
@@ -206,7 +204,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
|
||||
@NotNull
|
||||
private static Set<VirtualFile> getFilesWithFunctionalExpressionsScope(Project project, GlobalSearchScope useScope) {
|
||||
final Set<VirtualFile> files = newLinkedHashSet();
|
||||
final Set<VirtualFile> files = ContainerUtil.newLinkedHashSet();
|
||||
final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project);
|
||||
Processor<VirtualFile> processor = Processors.cancelableCollectProcessor(files);
|
||||
helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor);
|
||||
@@ -221,8 +219,8 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
scope = (GlobalSearchScope)useScope;
|
||||
}
|
||||
else if (useScope instanceof LocalSearchScope) {
|
||||
final Set<VirtualFile> files = new HashSet<VirtualFile>();
|
||||
addAllNotNull(files, map(((LocalSearchScope)useScope).getScope(), element -> PsiUtilCore.getVirtualFile(element)));
|
||||
final Set<VirtualFile> files = new HashSet<>();
|
||||
ContainerUtil.addAllNotNull(files, ContainerUtil.map(((LocalSearchScope)useScope).getScope(), PsiUtilCore::getVirtualFile));
|
||||
scope = GlobalSearchScope.filesScope(project, files);
|
||||
}
|
||||
else {
|
||||
@@ -247,15 +245,15 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
}
|
||||
</pre>
|
||||
*/
|
||||
private static void collectFilesWithTypeOccurrencesAndFieldAssignments(PsiClass aClass,
|
||||
GlobalSearchScope filesScope,
|
||||
final LinkedHashSet<VirtualFile> usageFiles) {
|
||||
final Set<PsiField> fields = new LinkedHashSet<PsiField>();
|
||||
private static void collectFilesWithTypeOccurrencesAndFieldAssignments(@NotNull PsiClass aClass,
|
||||
@NotNull GlobalSearchScope filesScope,
|
||||
@NotNull Set<VirtualFile> usageFiles) {
|
||||
final Set<PsiField> fields = new LinkedHashSet<>();
|
||||
for (final PsiReference reference : ReferencesSearch.search(aClass, filesScope)) {
|
||||
ApplicationManager.getApplication().runReadAction(() -> {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element != null) {
|
||||
addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element));
|
||||
ContainerUtil.addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element));
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiTypeElement) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
@@ -276,7 +274,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
final PsiElement fieldElement = fieldRef.getElement();
|
||||
final PsiAssignmentExpression varElementParent = PsiTreeUtil.getParentOfType(fieldElement, PsiAssignmentExpression.class);
|
||||
if (varElementParent != null && PsiTreeUtil.isAncestor(varElementParent.getLExpression(), fieldElement, false)) {
|
||||
addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement));
|
||||
ContainerUtil.addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -291,7 +289,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
VirtualFile file) {
|
||||
final PsiFile psiFile = aClass.getManager().findFile(file);
|
||||
if (psiFile != null) {
|
||||
final Ref<Boolean> ref = new Ref<Boolean>(true);
|
||||
final Ref<Boolean> ref = new Ref<>(true);
|
||||
psiFile.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
@@ -345,11 +343,11 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
private final boolean myVarArgs;
|
||||
private final PsiParameter[] myParameters;
|
||||
|
||||
public SuitableFilesProcessor(Map<VirtualFile, Set<JavaFunctionalExpressionIndex.IndexHolder>> holders,
|
||||
int expectedFunExprParamsCount,
|
||||
int parametersCount,
|
||||
boolean varArgs,
|
||||
PsiParameter[] parameters) {
|
||||
SuitableFilesProcessor(Map<VirtualFile, Set<JavaFunctionalExpressionIndex.IndexHolder>> holders,
|
||||
int expectedFunExprParamsCount,
|
||||
int parametersCount,
|
||||
boolean varArgs,
|
||||
PsiParameter[] parameters) {
|
||||
myHolders = holders;
|
||||
myExpectedFunExprParamsCount = expectedFunExprParamsCount;
|
||||
myParametersCount = parametersCount;
|
||||
@@ -372,7 +370,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
|
||||
}
|
||||
if (suitableParamNumbers) {
|
||||
if (savedHolders == null) {
|
||||
savedHolders = new LinkedHashSet<JavaFunctionalExpressionIndex.IndexHolder>();
|
||||
savedHolders = new LinkedHashSet<>();
|
||||
myHolders.put(file, savedHolders);
|
||||
}
|
||||
savedHolders.add(holder);
|
||||
|
||||
+1
-2
@@ -116,11 +116,10 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, O
|
||||
|
||||
@NotNull
|
||||
private static Iterable<PsiMethod> compute(@NotNull PsiMethod method, @NotNull Project project) {
|
||||
Collection<PsiMethod> result = new LinkedHashSet<>();
|
||||
|
||||
Application application = ApplicationManager.getApplication();
|
||||
final PsiClass containingClass = application.runReadAction((Computable<PsiClass>)method::getContainingClass);
|
||||
assert containingClass != null;
|
||||
Collection<PsiMethod> result = new LinkedHashSet<>();
|
||||
Processor<PsiClass> inheritorsProcessor = inheritor -> {
|
||||
PsiMethod found = application.runReadAction((Computable<PsiMethod>)() -> findOverridingMethod(project, inheritor, method, containingClass));
|
||||
if (found != null) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
@@ -38,12 +37,7 @@ public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
|
||||
super(delegate);
|
||||
|
||||
Project project = getProject();
|
||||
if (project != null) {
|
||||
myIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
}
|
||||
else {
|
||||
myIndex = null;
|
||||
}
|
||||
myIndex = project == null ? null : ProjectRootManager.getInstance(project).getFileIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-6
@@ -34,16 +34,16 @@ public class MethodDeepestSuperSearcher implements QueryExecutor<PsiMethod, PsiM
|
||||
return processDeepestSuperMethods(method, consumer);
|
||||
}
|
||||
|
||||
public static boolean processDeepestSuperMethods(PsiMethod method, Processor<PsiMethod> consumer) {
|
||||
final Set<PsiMethod> methods = new THashSet<PsiMethod>();
|
||||
public static boolean processDeepestSuperMethods(@NotNull PsiMethod method, @NotNull Processor<PsiMethod> consumer) {
|
||||
final Set<PsiMethod> methods = new THashSet<>();
|
||||
methods.add(method);
|
||||
return findDeepestSuperOrSelfSignature(method, methods, null, consumer);
|
||||
}
|
||||
|
||||
private static boolean findDeepestSuperOrSelfSignature(final PsiMethod method,
|
||||
Set<PsiMethod> set,
|
||||
private static boolean findDeepestSuperOrSelfSignature(@NotNull PsiMethod method,
|
||||
@NotNull Set<PsiMethod> set,
|
||||
Set<PsiMethod> guard,
|
||||
Processor<PsiMethod> processor) {
|
||||
@NotNull Processor<PsiMethod> processor) {
|
||||
if (guard != null && !guard.add(method)) return true;
|
||||
PsiMethod[] supers = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
|
||||
@Override
|
||||
@@ -57,7 +57,7 @@ public class MethodDeepestSuperSearcher implements QueryExecutor<PsiMethod, PsiM
|
||||
}
|
||||
for (PsiMethod superMethod : supers) {
|
||||
if (guard == null) {
|
||||
guard = new THashSet<PsiMethod>();
|
||||
guard = new THashSet<>();
|
||||
guard.add(method);
|
||||
}
|
||||
if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) return false;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, Method
|
||||
|
||||
final SearchRequestCollector collector = p.getOptimizer();
|
||||
|
||||
final SearchScope searchScope = DumbService.getInstance(p.getProject()).runReadActionInSmartMode(() -> p.getEffectiveSearchScope());
|
||||
final SearchScope searchScope = DumbService.getInstance(p.getProject()).runReadActionInSmartMode(p::getEffectiveSearchScope);
|
||||
if (searchScope == GlobalSearchScope.EMPTY_SCOPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-1
@@ -65,7 +65,8 @@ public class PsiAnnotationMethodReferencesSearcher implements QueryExecutor<PsiR
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ReadActionProcessor<PsiReference> createImplicitDefaultAnnotationMethodConsumer(final Processor<PsiReference> consumer) {
|
||||
@NotNull
|
||||
static ReadActionProcessor<PsiReference> createImplicitDefaultAnnotationMethodConsumer(@NotNull Processor<PsiReference> consumer) {
|
||||
return new ReadActionProcessor<PsiReference>() {
|
||||
@Override
|
||||
public boolean processInReadAction(final PsiReference reference) {
|
||||
|
||||
+1
-2
@@ -34,7 +34,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author ven
|
||||
*/
|
||||
public class SimpleAccessorReferenceSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
|
||||
|
||||
public SimpleAccessorReferenceSearcher() {
|
||||
super(true);
|
||||
}
|
||||
@@ -47,7 +46,7 @@ public class SimpleAccessorReferenceSearcher extends QueryExecutorBase<PsiRefere
|
||||
addPropertyAccessUsages((PsiMethod)refElement, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer());
|
||||
}
|
||||
|
||||
static void addPropertyAccessUsages(PsiMethod method, SearchScope scope, SearchRequestCollector collector) {
|
||||
static void addPropertyAccessUsages(@NotNull PsiMethod method, @NotNull SearchScope scope, @NotNull SearchRequestCollector collector) {
|
||||
final String propertyName = PropertyUtil.getPropertyName(method);
|
||||
if (StringUtil.isNotEmpty(propertyName)) {
|
||||
SearchScope additional = GlobalSearchScope.EMPTY_SCOPE;
|
||||
|
||||
+8
@@ -16,10 +16,12 @@
|
||||
package com.intellij.psi.impl.search;
|
||||
|
||||
import com.intellij.openapi.application.QueryExecutorBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil;
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
|
||||
@@ -33,6 +35,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author peter
|
||||
*/
|
||||
public class StubHierarchyInheritorSearcher extends QueryExecutorBase<PsiClass, DirectClassInheritorsSearch.SearchParameters> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.StubHierarchyInheritorSearcher");
|
||||
public StubHierarchyInheritorSearcher() {
|
||||
super(true);
|
||||
}
|
||||
@@ -54,6 +57,11 @@ public class StubHierarchyInheritorSearcher extends QueryExecutorBase<PsiClass,
|
||||
if (!(p.getScope() instanceof GlobalSearchScope) || !isSearching()) return;
|
||||
|
||||
PsiClass base = p.getClassToProcess();
|
||||
PsiElement original = base.getOriginalElement();
|
||||
if (original instanceof PsiClass) {
|
||||
base = (PsiClass)original;
|
||||
}
|
||||
|
||||
GlobalSearchScope scope = (GlobalSearchScope)p.getScope();
|
||||
ClassHierarchy hierarchy = HierarchyService.getHierarchy(base.getProject());
|
||||
for (SmartClassAnchor anchor : hierarchy.getDirectSubtypeCandidates(base)) {
|
||||
|
||||
+12
-15
@@ -50,24 +50,21 @@ public class VariableInIncompleteCodeSearcher extends QueryExecutorBase<PsiRefer
|
||||
PsiElement[] elements = ((LocalSearchScope)scope).getScope();
|
||||
if (elements.length == 0) return;
|
||||
|
||||
PsiSearchHelper.SERVICE.getInstance(p.getProject()).processElementsWithWord(new TextOccurenceProcessor() {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, int offsetInElement) {
|
||||
for (PsiElement child = element.findElementAt(offsetInElement); child != null; child = child.getParent()) {
|
||||
if (!name.equals(child.getText())) {
|
||||
break;
|
||||
}
|
||||
if (child instanceof PsiJavaCodeReferenceElement) {
|
||||
final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)child;
|
||||
if (!ref.isQualified() &&
|
||||
!(ref.getParent() instanceof PsiMethodCallExpression) &&
|
||||
ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) {
|
||||
consumer.process(ref);
|
||||
}
|
||||
PsiSearchHelper.SERVICE.getInstance(p.getProject()).processElementsWithWord((element, offsetInElement) -> {
|
||||
for (PsiElement child = element.findElementAt(offsetInElement); child != null; child = child.getParent()) {
|
||||
if (!name.equals(child.getText())) {
|
||||
break;
|
||||
}
|
||||
if (child instanceof PsiJavaCodeReferenceElement) {
|
||||
final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)child;
|
||||
if (!ref.isQualified() &&
|
||||
!(ref.getParent() instanceof PsiMethodCallExpression) &&
|
||||
ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) {
|
||||
consumer.process(ref);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}, scope, name, UsageSearchContext.ANY, true);
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -74,6 +74,10 @@ public class JavaGenericsUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type instanceof PsiCapturedWildcardType) {
|
||||
return isReifiableType(((PsiCapturedWildcardType)type).getUpperBound());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,6 +131,9 @@ public class JavaGenericsUtil {
|
||||
if (castType instanceof PsiClassType) {
|
||||
final PsiClassType castClassType = (PsiClassType)castType;
|
||||
operandType = operandType.getDeepComponentType();
|
||||
if (operandType instanceof PsiCapturedWildcardType) {
|
||||
operandType = ((PsiCapturedWildcardType)operandType).getUpperBound();
|
||||
}
|
||||
|
||||
if (!(operandType instanceof PsiClassType)) return false;
|
||||
final PsiClassType operandClassType = (PsiClassType)operandType;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.psi;
|
||||
import com.intellij.psi.javadoc.*;
|
||||
|
||||
public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
|
||||
public void visitAnonymousClass(PsiAnonymousClass aClass) {
|
||||
visitClass(aClass);
|
||||
}
|
||||
@@ -387,4 +386,28 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
visitExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitModule(PsiJavaModule module) {
|
||||
visitElement(module);
|
||||
}
|
||||
|
||||
public void visitModuleReference(PsiJavaModuleReference moduleRef) {
|
||||
visitElement(moduleRef);
|
||||
}
|
||||
|
||||
public void visitRequiresStatement(PsiRequiresStatement statement) {
|
||||
visitElement(statement);
|
||||
}
|
||||
|
||||
public void visitExportsStatement(PsiExportsStatement statement) {
|
||||
visitElement(statement);
|
||||
}
|
||||
|
||||
public void visitUsesStatement(PsiUsesStatement statement) {
|
||||
visitElement(statement);
|
||||
}
|
||||
|
||||
public void visitProvidesStatement(PsiProvidesStatement statement) {
|
||||
visitElement(statement);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -139,4 +139,12 @@ public interface JavaTokenType extends TokenType {
|
||||
|
||||
IElementType DOUBLE_COLON = new IJavaElementType("DOUBLE_COLON");
|
||||
IElementType ARROW = new IJavaElementType("ARROW");
|
||||
}
|
||||
|
||||
IElementType MODULE_KEYWORD = new IJavaElementType("MODULE");
|
||||
IElementType REQUIRES_KEYWORD = new IJavaElementType("REQUIRES");
|
||||
IElementType EXPORTS_KEYWORD = new IJavaElementType("EXPORTS");
|
||||
IElementType USES_KEYWORD = new IJavaElementType("USES");
|
||||
IElementType PROVIDES_KEYWORD = new IJavaElementType("PROVIDES");
|
||||
IElementType TO_KEYWORD = new IJavaElementType("TO");
|
||||
IElementType WITH_KEYWORD = new IJavaElementType("WITH");
|
||||
}
|
||||
+9
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -13,16 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.concurrency;
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
|
||||
public abstract class ConsumerRunnable implements Consumer<Void>, Runnable {
|
||||
@Override
|
||||
public final void consume(Void aVoid) {
|
||||
run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void run();
|
||||
}
|
||||
/**
|
||||
* Represents an {@code exports} statement of a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiExportsStatement extends PsiElement {
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
/**
|
||||
* Represents a Java, JSP or class file.
|
||||
* Represents a Java, JSP or .class file.
|
||||
*/
|
||||
public interface PsiJavaFile extends PsiImportHolder, PsiClassOwner {
|
||||
/**
|
||||
@@ -91,4 +91,9 @@ public interface PsiJavaFile extends PsiImportHolder, PsiClassOwner {
|
||||
@Nullable PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass);
|
||||
|
||||
@NotNull LanguageLevel getLanguageLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Java module declaration element, or {@code null} if the file is not a module-info one.
|
||||
*/
|
||||
@Nullable PsiJavaModule getModuleDeclaration();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiJavaModule extends PsiElement {
|
||||
@Nullable PsiJavaModuleReference getNameElement();
|
||||
@Nullable String getModuleName();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents a reference to some module inside a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiJavaModuleReference extends PsiElement {
|
||||
@NotNull String getReferenceText();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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,7 +19,6 @@ package com.intellij.psi;
|
||||
* Represents a Java keyword. Constants defined in this interface represent all
|
||||
* keywords of the Java language.
|
||||
*/
|
||||
@SuppressWarnings({"HardCodedStringLiteral", "JavaDoc"})
|
||||
public interface PsiKeyword extends PsiJavaToken {
|
||||
String ABSTRACT = "abstract";
|
||||
String ASSERT = "assert";
|
||||
@@ -75,4 +74,12 @@ public interface PsiKeyword extends PsiJavaToken {
|
||||
String TRUE = "true";
|
||||
String FALSE = "false";
|
||||
String NULL = "null";
|
||||
}
|
||||
|
||||
String MODULE = "module";
|
||||
String REQUIRES = "requires";
|
||||
String EXPORTS = "exports";
|
||||
String USES = "uses";
|
||||
String PROVIDES = "provides";
|
||||
String TO = "to";
|
||||
String WITH = "with";
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi;
|
||||
|
||||
/**
|
||||
* Represents a {@code provides} statement of a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiProvidesStatement extends PsiElement {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi;
|
||||
|
||||
/**
|
||||
* Represents a {@code requires} statement of a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiRequiresStatement extends PsiElement {
|
||||
}
|
||||
+8
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -13,11 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.concurrency;
|
||||
package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface AsyncFunction<PARAM, RESULT> {
|
||||
@NotNull
|
||||
Promise<RESULT> fun(PARAM param);
|
||||
/**
|
||||
* Represents a {@code uses} statement of a Java module declaration.
|
||||
*
|
||||
* @since 2016.3
|
||||
*/
|
||||
public interface PsiUsesStatement extends PsiElement {
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -87,7 +87,7 @@ public abstract class JavaCodeStyleManager {
|
||||
* file if an Optimize Imports operation was performed on it.
|
||||
*
|
||||
* @param file the file to calculate the import list for.
|
||||
* @return the calculated import list.
|
||||
* @return the calculated import list, or {@code null} when the file has no import list.
|
||||
*/
|
||||
public abstract PsiImportList prepareOptimizeImportsResult(@NotNull PsiJavaFile file);
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ public class PropertyUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getPropertyName(@NonNls String methodName) {
|
||||
public static String getPropertyName(@NonNls @NotNull String methodName) {
|
||||
return StringUtil.getPropertyName(methodName);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.psi.util;
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
@@ -24,7 +23,6 @@ import com.intellij.openapi.projectRoots.JavaVersionService;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
@@ -629,7 +627,10 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
* <code>class Foo<T extends Number>{}</code> types Foo<?> and Foo<? extends Number>
|
||||
* would be equivalent
|
||||
*/
|
||||
public static boolean equalOnEquivalentClasses(PsiClassType thisClassType, @NotNull PsiClass aClass, PsiClassType otherClassType, @NotNull PsiClass bClass) {
|
||||
public static boolean equalOnEquivalentClasses(PsiClassType thisClassType,
|
||||
@NotNull PsiClass aClass,
|
||||
PsiClassType otherClassType,
|
||||
@NotNull PsiClass bClass) {
|
||||
final PsiClassType capture1 = !PsiCapturedWildcardType.isCapture()
|
||||
? thisClassType : (PsiClassType)captureToplevelWildcards(thisClassType, aClass);
|
||||
final PsiClassType capture2 = !PsiCapturedWildcardType.isCapture()
|
||||
@@ -641,17 +642,10 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return equalOnEquivalentClasses(result1.getSubstitutor(), aClass, result2.getSubstitutor(), bClass);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean equalOnClass(@NotNull PsiSubstitutor s1, @NotNull PsiSubstitutor s2, @NotNull PsiClass aClass) {
|
||||
return equalOnEquivalentClasses(s1, aClass, s2, aClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated to remove in v.16
|
||||
* Checks if substitutors maps are identical. If substitutor map values contain wildcard type, type parameter bounds are IGNORED.
|
||||
* Please use {@link PsiUtil#equalOnEquivalentClasses(PsiClassType, PsiClass, PsiClassType, PsiClass)} instead.
|
||||
*/
|
||||
public static boolean equalOnEquivalentClasses(@NotNull PsiSubstitutor s1, @NotNull PsiClass aClass, @NotNull PsiSubstitutor s2, @NotNull PsiClass bClass) {
|
||||
private static boolean equalOnEquivalentClasses(@NotNull PsiSubstitutor s1,
|
||||
@NotNull PsiClass aClass,
|
||||
@NotNull PsiSubstitutor s2,
|
||||
@NotNull PsiClass bClass) {
|
||||
// assume generic class equals to non-generic
|
||||
if (aClass.hasTypeParameters() != bClass.hasTypeParameters()) return true;
|
||||
final PsiTypeParameter[] typeParameters1 = aClass.getTypeParameters();
|
||||
@@ -673,9 +667,8 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return containingClass1 == null && containingClass2 == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use more generic {@link #isCompileTimeConstant(PsiVariable)} instead
|
||||
*/
|
||||
/** @deprecated use more generic {@link #isCompileTimeConstant(PsiVariable)} instead */
|
||||
@SuppressWarnings("unused")
|
||||
public static boolean isCompileTimeConstant(@NotNull final PsiField field) {
|
||||
return isCompileTimeConstant((PsiVariable)field);
|
||||
}
|
||||
@@ -883,11 +876,6 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return psiClass != null && psiClass.isAnnotationType();
|
||||
}
|
||||
|
||||
@PsiModifier.ModifierConstant
|
||||
public static String getMaximumModifierForMember(final PsiClass aClass) {
|
||||
return getMaximumModifierForMember(aClass, true);
|
||||
}
|
||||
|
||||
@PsiModifier.ModifierConstant
|
||||
public static String getMaximumModifierForMember(final PsiClass aClass, boolean allowPublicAbstract) {
|
||||
String modifier = PsiModifier.PUBLIC;
|
||||
@@ -1294,281 +1282,7 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
}
|
||||
}
|
||||
|
||||
public static class NullPsiClass extends NullPsiElement implements PsiClass {
|
||||
@Nullable
|
||||
@Override
|
||||
public ItemPresentation getPresentation() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiDocComment getDocComment() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTypeParameters() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiModifierList getModifierList() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeprecated() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiTypeParameterList getTypeParameterList() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void navigate(boolean requestFocus) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNavigate() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModifierProperty(@PsiModifier.ModifierConstant @NonNls @NotNull String name) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeParameter[] getTypeParameters() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNavigateToSource() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotationType() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnum() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiReferenceList getExtendsList() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiReferenceList getImplementsList() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getExtendsListTypes() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getImplementsListTypes() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass getSuperClass() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass[] getInterfaces() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] getSupers() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getSuperTypes() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiField[] getFields() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] getMethods() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] getConstructors() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] getInnerClasses() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassInitializer[] getInitializers() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiField[] getAllFields() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] getAllMethods() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] getAllInnerClasses() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiField findFieldByName(@NonNls String name, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement getLBrace() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement getRBrace() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiIdentifier getNameIdentifier() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getScope() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass getContainingClass() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<HierarchicalMethodSignature> getVisibleSignatures() {
|
||||
throw createException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement setName(@NonNls @NotNull String name) {
|
||||
throw createException();
|
||||
}
|
||||
public static boolean isModuleFile(@NotNull PsiFile file) {
|
||||
return file instanceof PsiJavaFile && ((PsiJavaFile)file).getModuleDeclaration() != null;
|
||||
}
|
||||
|
||||
public static final PsiClass NULL_PSI_CLASS = new NullPsiClass();
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,6 @@ jdk.1.5.language.level.description=5.0 - 'enum' keyword, generics, autoboxing et
|
||||
jdk.1.6.language.level.description=6 - @Override in interfaces
|
||||
jdk.1.7.language.level.description=7 - Diamonds, ARM, multi-catch etc.
|
||||
jdk.1.8.language.level.description=8 - Lambdas, type annotations etc.
|
||||
jdk.1.9.language.level.description=9 - JDK modularization etc.
|
||||
jdk.1.9.language.level.description=9 - Modules, private methods in interfaces etc.
|
||||
|
||||
jdk.X.language.level.description=X - Experimental features
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -53,6 +54,11 @@ public class FileParser {
|
||||
@NotNull final TokenSet importListStoppers,
|
||||
@NotNull final AbstractBundle bundle,
|
||||
@NotNull final String errorMessageKey) {
|
||||
if (PsiKeyword.MODULE.equals(builder.getTokenText())) {
|
||||
ModuleParser.parseModule(builder);
|
||||
return;
|
||||
}
|
||||
|
||||
parsePackageStatement(builder);
|
||||
|
||||
Pair<PsiBuilder.Marker, Boolean> impListInfo = parseImportList(builder, importListStoppers);
|
||||
@@ -189,4 +195,4 @@ public class FileParser {
|
||||
done(statement, type);
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.lang.java.parser;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiKeyword;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.error;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.semicolon;
|
||||
|
||||
public class ModuleParser {
|
||||
public static void parseModule(@NotNull PsiBuilder builder) {
|
||||
PsiBuilder.Marker module = builder.mark();
|
||||
mapAndAdvance(builder, JavaTokenType.MODULE_KEYWORD);
|
||||
|
||||
if (parseName(builder) == null) {
|
||||
module.drop();
|
||||
if (builder.getTokenType() != null) {
|
||||
parseExtras(builder, JavaErrorMessages.message("expected.module.declaration"));
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.LBRACE)) {
|
||||
if (builder.getTokenType() != null) {
|
||||
parseExtras(builder, JavaErrorMessages.message("expected.module.declaration"));
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.lbrace"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
parseModuleContent(builder);
|
||||
}
|
||||
|
||||
module.done(JavaElementType.MODULE);
|
||||
|
||||
if (builder.getTokenType() != null) {
|
||||
parseExtras(builder, JavaErrorMessages.message("unexpected.tokens"));
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseName(PsiBuilder builder) {
|
||||
PsiBuilder.Marker nameElement = builder.mark();
|
||||
boolean empty = true;
|
||||
|
||||
boolean idExpected = true;
|
||||
while (true) {
|
||||
IElementType t = builder.getTokenType();
|
||||
if (t == JavaTokenType.IDENTIFIER) {
|
||||
if (!idExpected) error(builder, JavaErrorMessages.message("expected.dot"));
|
||||
idExpected = false;
|
||||
}
|
||||
else if (t == JavaTokenType.DOT) {
|
||||
if (idExpected) error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
idExpected = true;
|
||||
}
|
||||
else break;
|
||||
builder.advanceLexer();
|
||||
empty = false;
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
if (idExpected) error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
nameElement.done(JavaElementType.MODULE_REFERENCE);
|
||||
return nameElement;
|
||||
}
|
||||
else {
|
||||
nameElement.drop();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseModuleContent(PsiBuilder builder) {
|
||||
IElementType token;
|
||||
PsiBuilder.Marker invalid = null;
|
||||
|
||||
while ((token = builder.getTokenType()) != null) {
|
||||
if (token == JavaTokenType.RBRACE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (token == JavaTokenType.SEMICOLON) {
|
||||
if (invalid != null) {
|
||||
invalid.error(JavaErrorMessages.message("expected.module.statement"));
|
||||
invalid = null;
|
||||
}
|
||||
builder.advanceLexer();
|
||||
continue;
|
||||
}
|
||||
|
||||
PsiBuilder.Marker statement = parseStatement(builder);
|
||||
if (statement == null) {
|
||||
if (invalid == null) invalid = builder.mark();
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else if (invalid != null) {
|
||||
invalid.errorBefore(JavaErrorMessages.message("expected.module.statement"), statement);
|
||||
invalid = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid != null) {
|
||||
invalid.error(JavaErrorMessages.message("expected.module.statement"));
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.RBRACE) && invalid == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.rbrace"));
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseStatement(PsiBuilder builder) {
|
||||
String kw = builder.getTokenText();
|
||||
if (PsiKeyword.REQUIRES.equals(kw)) return parseRequiresStatement(builder);
|
||||
if (PsiKeyword.EXPORTS.equals(kw)) return parseExportsStatement(builder);
|
||||
if (PsiKeyword.USES.equals(kw)) return parseUsesStatement(builder);
|
||||
if (PsiKeyword.PROVIDES.equals(kw)) return parseProvidesStatement(builder);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseRequiresStatement(PsiBuilder builder) {
|
||||
PsiBuilder.Marker statement = builder.mark();
|
||||
mapAndAdvance(builder, JavaTokenType.REQUIRES_KEYWORD);
|
||||
|
||||
expect(builder, JavaTokenType.PUBLIC_KEYWORD);
|
||||
|
||||
if (parseNameRef(builder) != null) {
|
||||
semicolon(builder);
|
||||
}
|
||||
else {
|
||||
expect(builder, JavaTokenType.SEMICOLON);
|
||||
}
|
||||
|
||||
statement.done(JavaElementType.REQUIRES_STATEMENT);
|
||||
return statement;
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseExportsStatement(PsiBuilder builder) {
|
||||
PsiBuilder.Marker statement = builder.mark();
|
||||
boolean hasError = false;
|
||||
mapAndAdvance(builder, JavaTokenType.EXPORTS_KEYWORD);
|
||||
|
||||
if (parseClassOrPackageRef(builder) != null) {
|
||||
if (PsiKeyword.TO.equals(builder.getTokenText())) {
|
||||
mapAndAdvance(builder, JavaTokenType.TO_KEYWORD);
|
||||
|
||||
while (true) {
|
||||
PsiBuilder.Marker ref = parseNameRef(builder);
|
||||
if (!expect(builder, JavaTokenType.COMMA)) {
|
||||
if (ref == null) hasError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.package.reference"));
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!hasError) {
|
||||
semicolon(builder);
|
||||
}
|
||||
else {
|
||||
expect(builder, JavaTokenType.SEMICOLON);
|
||||
}
|
||||
|
||||
statement.done(JavaElementType.EXPORTS_STATEMENT);
|
||||
return statement;
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseUsesStatement(PsiBuilder builder) {
|
||||
PsiBuilder.Marker statement = builder.mark();
|
||||
mapAndAdvance(builder, JavaTokenType.USES_KEYWORD);
|
||||
|
||||
if (parseClassOrPackageRef(builder) != null) {
|
||||
semicolon(builder);
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.class.reference"));
|
||||
expect(builder, JavaTokenType.SEMICOLON);
|
||||
}
|
||||
|
||||
statement.done(JavaElementType.USES_STATEMENT);
|
||||
return statement;
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseProvidesStatement(PsiBuilder builder) {
|
||||
PsiBuilder.Marker statement = builder.mark();
|
||||
boolean hasError = false;
|
||||
mapAndAdvance(builder, JavaTokenType.PROVIDES_KEYWORD);
|
||||
|
||||
if (parseClassOrPackageRef(builder) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.class.reference"));
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (PsiKeyword.WITH.equals(builder.getTokenText())) {
|
||||
mapAndAdvance(builder, JavaTokenType.WITH_KEYWORD);
|
||||
if (parseClassOrPackageRef(builder) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.class.reference"));
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
else if (!hasError) {
|
||||
error(builder, JavaErrorMessages.message("expected.with"));
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!hasError) {
|
||||
semicolon(builder);
|
||||
}
|
||||
else {
|
||||
expect(builder, JavaTokenType.SEMICOLON);
|
||||
}
|
||||
|
||||
statement.done(JavaElementType.PROVIDES_STATEMENT);
|
||||
return statement;
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseNameRef(PsiBuilder builder) {
|
||||
PsiBuilder.Marker name = parseName(builder);
|
||||
if (name == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static void mapAndAdvance(PsiBuilder builder, IElementType keyword) {
|
||||
builder.remapCurrentToken(keyword);
|
||||
builder.advanceLexer();
|
||||
}
|
||||
|
||||
private static void parseExtras(PsiBuilder builder, String message) {
|
||||
PsiBuilder.Marker extras = builder.mark();
|
||||
while (builder.getTokenType() != null) builder.advanceLexer();
|
||||
extras.error(message);
|
||||
}
|
||||
|
||||
private static PsiBuilder.Marker parseClassOrPackageRef(PsiBuilder builder) {
|
||||
return JavaParser.INSTANCE.getReferenceParser().parseJavaCodeReference(builder, true, false, false, false);
|
||||
}
|
||||
}
|
||||
@@ -183,11 +183,7 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
|
||||
if (type instanceof PsiClassReferenceType) {
|
||||
return ((PsiClassReferenceType)type).getReference();
|
||||
}
|
||||
|
||||
final PsiClassType.ClassResolveResult resolveResult = type.resolveGenerics();
|
||||
final PsiClass refClass = resolveResult.getElement();
|
||||
assert refClass != null : type;
|
||||
return new LightClassReference(myManager, type.getCanonicalText(true), refClass, resolveResult.getSubstitutor());
|
||||
return new LightClassTypeReference(myManager, type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -256,6 +256,12 @@ public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
|
||||
return level;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiJavaModule getModuleDeclaration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement setName(@NotNull String name) throws IncorrectOperationException {
|
||||
throw cannotModifyException(this);
|
||||
|
||||
@@ -15,27 +15,21 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.light;
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LightClassReference extends LightElement implements PsiJavaCodeReferenceElement {
|
||||
private final String myText;
|
||||
public class LightClassReference extends LightClassReferenceBase implements PsiJavaCodeReferenceElement {
|
||||
|
||||
private final String myClassName;
|
||||
private final PsiElement myContext;
|
||||
@NotNull private final GlobalSearchScope myResolveScope;
|
||||
private final PsiClass myRefClass;
|
||||
private final PsiSubstitutor mySubstitutor;
|
||||
|
||||
private LightReferenceParameterList myParameterList;
|
||||
|
||||
private LightClassReference(@NotNull PsiManager manager,
|
||||
@NotNull @NonNls String text,
|
||||
@Nullable @NonNls String className,
|
||||
@@ -43,8 +37,7 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
@NotNull GlobalSearchScope resolveScope,
|
||||
@Nullable PsiElement context,
|
||||
@Nullable PsiClass refClass) {
|
||||
super(manager, JavaLanguage.INSTANCE);
|
||||
myText = text;
|
||||
super(manager, text);
|
||||
myClassName = className;
|
||||
myResolveScope = resolveScope;
|
||||
|
||||
@@ -107,32 +100,6 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
return new CandidateInfo(resolved, substitutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult[] multiResolve(boolean incompleteCode){
|
||||
final JavaResolveResult result = advancedResolve(incompleteCode);
|
||||
if(result != JavaResolveResult.EMPTY) return new JavaResolveResult[]{result};
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processVariants(@NotNull PsiScopeProcessor processor){
|
||||
throw new RuntimeException("Variants are not available for light references");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getReferenceNameElement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceParameterList getParameterList() {
|
||||
if (myParameterList == null) {
|
||||
myParameterList = new LightReferenceParameterList(myManager, PsiTypeElement.EMPTY_ARRAY);
|
||||
}
|
||||
return myParameterList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
if (myClassName != null) {
|
||||
@@ -162,36 +129,6 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
String name = getQualifiedName();
|
||||
if (name == null) return "";
|
||||
PsiType[] types = getTypeParameters();
|
||||
if (types.length == 0) return name;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(name);
|
||||
buf.append('<');
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (i > 0) buf.append(',');
|
||||
buf.append(types[i].getCanonicalText());
|
||||
}
|
||||
buf.append('>');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement copy() {
|
||||
if (myClassName != null) {
|
||||
@@ -207,79 +144,11 @@ public class LightClassReference extends LightElement implements PsiJavaCodeRefe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
//TODO?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
//TODO?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitReferenceElement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "LightClassReference:" + myText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return element instanceof PsiClass && getManager().areElementsEquivalent(resolve(), element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
throw new RuntimeException("Variants are not available for light references");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return new TextRange(0, getTextLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myRefClass == null || myRefClass.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiType[] getTypeParameters() {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getQualifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.light;
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
abstract class LightClassReferenceBase extends LightElement implements PsiJavaCodeReferenceElement {
|
||||
|
||||
protected final String myText;
|
||||
|
||||
private LightReferenceParameterList myParameterList;
|
||||
|
||||
protected LightClassReferenceBase(@NotNull PsiManager manager, @NotNull String text) {
|
||||
super(manager, JavaLanguage.INSTANCE);
|
||||
myText = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
final JavaResolveResult result = advancedResolve(incompleteCode);
|
||||
if (result != JavaResolveResult.EMPTY) return new JavaResolveResult[]{result};
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processVariants(@NotNull PsiScopeProcessor processor) {
|
||||
throw new RuntimeException("Variants are not available for light references");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getReferenceNameElement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceParameterList getParameterList() {
|
||||
if (myParameterList == null) {
|
||||
myParameterList = new LightReferenceParameterList(myManager, PsiTypeElement.EMPTY_ARRAY);
|
||||
}
|
||||
return myParameterList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
PsiClass psiClass = (PsiClass)resolve();
|
||||
if (psiClass != null) {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
String name = getQualifiedName();
|
||||
if (name == null) return "";
|
||||
PsiType[] types = getTypeParameters();
|
||||
if (types.length == 0) return name;
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(name);
|
||||
buf.append('<');
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (i > 0) buf.append(',');
|
||||
buf.append(types[i].getCanonicalText());
|
||||
}
|
||||
buf.append('>');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
//TODO?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
//TODO?
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitReferenceElement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return element instanceof PsiClass && getManager().areElementsEquivalent(resolve(), element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
throw new RuntimeException("Variants are not available for light references");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return new TextRange(0, getTextLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiType[] getTypeParameters() {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getQualifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.light;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class LightClassTypeReference extends LightClassReferenceBase implements PsiJavaCodeReferenceElement {
|
||||
|
||||
private final @NotNull PsiClassType myType;
|
||||
|
||||
private LightClassTypeReference(@NotNull PsiManager manager, @NotNull String text, @NotNull PsiClassType type) {
|
||||
super(manager, text);
|
||||
myType = type;
|
||||
}
|
||||
|
||||
public LightClassTypeReference(@NotNull PsiManager manager, @NotNull PsiClassType type) {
|
||||
this(manager, type.getCanonicalText(true), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return myType.resolve();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
return myType.resolveGenerics();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getReferenceName() {
|
||||
return myType.getClassName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement copy() {
|
||||
return new LightClassTypeReference(myManager, myText, myType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myType.isValid();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
return myType.getResolveScope();
|
||||
}
|
||||
}
|
||||
@@ -183,15 +183,7 @@ public class PsiAnonymousClassImpl extends PsiClassImpl implements PsiAnonymousC
|
||||
@NotNull PsiElement place) {
|
||||
if (lastParent instanceof PsiExpressionList) return true;
|
||||
|
||||
final PsiClassStub stub = getStub();
|
||||
if (stub != null) {
|
||||
// no tree is loaded
|
||||
// that means we could not have come from resolving something inside anonymous class, we just resolving the base class reference
|
||||
// so skip the (very expensive) getBaseClassReference() call which would load tree
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastParent != null/* IMPORTANT: do not call getBaseClassReference() for lastParent == null and lastParent which is not under our node - loads tree!*/
|
||||
if (lastParent instanceof PsiJavaCodeReferenceElement/* IMPORTANT: do not call getBaseClassReference() for lastParent == null and lastParent which is not under our node - loads tree!*/
|
||||
&& lastParent.getParent() == this && lastParent == getBaseClassReference()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiExportsStatement;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiExportsStatementImpl extends CompositePsiElement implements PsiExportsStatement {
|
||||
public PsiExportsStatementImpl() {
|
||||
super(JavaElementType.EXPORTS_STATEMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitExportsStatement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiExportsStatement";
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.containers.MostlySingularMultiMap;
|
||||
import com.intellij.util.indexing.IndexingDataKeys;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -107,6 +108,10 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
|
||||
@Override
|
||||
public void setPackageName(final String packageName) throws IncorrectOperationException {
|
||||
if (PsiUtil.isModuleFile(this)) {
|
||||
throw new IncorrectOperationException("Cannot set package name for module declarations");
|
||||
}
|
||||
|
||||
final PsiPackageStatement packageStatement = getPackageStatement();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
|
||||
if (packageStatement != null) {
|
||||
@@ -118,36 +123,33 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
packageStatement.delete();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!packageName.isEmpty()) {
|
||||
addBefore(factory.createPackageStatement(packageName), getFirstChild());
|
||||
}
|
||||
else if (!packageName.isEmpty()) {
|
||||
addBefore(factory.createPackageStatement(packageName), getFirstChild());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiImportList getImportList() {
|
||||
StubElement<?> stub = getStub();
|
||||
if (stub != null) {
|
||||
PsiImportList[] nodes = stub.getChildrenByType(JavaStubElementTypes.IMPORT_LIST, PsiImportList.ARRAY_FACTORY);
|
||||
if (nodes.length != 1) {
|
||||
reportStubAstMismatch(stub + "; " + stub.getChildrenStubs(), getStubTree(), PsiDocumentManager.getInstance(getProject()).getCachedDocument(this));
|
||||
}
|
||||
return nodes[0];
|
||||
if (nodes.length == 1) return nodes[0];
|
||||
if (nodes.length == 0) return null;
|
||||
reportStubAstMismatch(stub + "; " + stub.getChildrenStubs(), getStubTree(), PsiDocumentManager.getInstance(getProject()).getCachedDocument(this));
|
||||
}
|
||||
|
||||
ASTNode node = calcTreeElement().findChildByType(JavaElementType.IMPORT_LIST);
|
||||
assert node != null : getFileType() + ", " + getName();
|
||||
return SourceTreeToPsiMap.treeToPsiNotNull(node);
|
||||
return (PsiImportList)SourceTreeToPsiMap.treeElementToPsi(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElement[] getOnDemandImports(boolean includeImplicit, boolean checkIncludes) {
|
||||
PsiImportList importList = getImportList();
|
||||
if (importList == null) return EMPTY_ARRAY;
|
||||
|
||||
List<PsiElement> array = new ArrayList<PsiElement>();
|
||||
|
||||
PsiImportList importList = getImportList();
|
||||
PsiImportStatement[] statements = importList.getImportStatements();
|
||||
for (PsiImportStatement statement : statements) {
|
||||
if (statement.isOnDemand()) {
|
||||
@@ -174,8 +176,10 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClass[] getSingleClassImports(boolean checkIncludes) {
|
||||
List<PsiClass> array = new ArrayList<PsiClass>();
|
||||
PsiImportList importList = getImportList();
|
||||
if (importList == null) return PsiClass.EMPTY_ARRAY;
|
||||
|
||||
List<PsiClass> array = new ArrayList<PsiClass>();
|
||||
PsiImportStatement[] statements = importList.getImportStatements();
|
||||
for (PsiImportStatement statement : statements) {
|
||||
if (!statement.isOnDemand()) {
|
||||
@@ -191,12 +195,14 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
@Override
|
||||
public PsiJavaCodeReferenceElement findImportReferenceTo(PsiClass aClass) {
|
||||
PsiImportList importList = getImportList();
|
||||
PsiImportStatement[] statements = importList.getImportStatements();
|
||||
for (PsiImportStatement statement : statements) {
|
||||
if (!statement.isOnDemand()) {
|
||||
PsiElement ref = statement.resolve();
|
||||
if (ref != null && getManager().areElementsEquivalent(ref, aClass)) {
|
||||
return statement.getImportReference();
|
||||
if (importList != null) {
|
||||
PsiImportStatement[] statements = importList.getImportStatements();
|
||||
for (PsiImportStatement statement : statements) {
|
||||
if (!statement.isOnDemand()) {
|
||||
PsiElement ref = statement.resolve();
|
||||
if (ref != null && getManager().areElementsEquivalent(ref, aClass)) {
|
||||
return statement.getImportReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,7 +322,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
if (!processor.execute(aClass, state)) return false;
|
||||
}
|
||||
|
||||
final PsiImportStatement[] importStatements = importList.getImportStatements();
|
||||
final PsiImportStatement[] importStatements = importList != null ? importList.getImportStatements() : PsiImportStatement.EMPTY_ARRAY;
|
||||
|
||||
// single-type processing
|
||||
for (PsiImportStatement statement : importStatements) {
|
||||
@@ -360,7 +366,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
}
|
||||
}
|
||||
|
||||
final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements();
|
||||
final PsiImportStaticStatement[] importStaticStatements = importList != null ? importList.getImportStaticStatements() : PsiImportStaticStatement.EMPTY_ARRAY;
|
||||
if (importStaticStatements.length > 0) {
|
||||
final StaticImportFilteringProcessor staticImportProcessor = new StaticImportFilteringProcessor(processor);
|
||||
|
||||
@@ -470,6 +476,12 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
|
||||
return LANGUAGE_LEVEL_KEY.getValue(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiJavaModule getModuleDeclaration() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCaches() {
|
||||
super.clearCaches();
|
||||
|
||||
@@ -17,21 +17,33 @@ package com.intellij.psi.impl.source;
|
||||
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiJavaFileImpl extends PsiJavaFileBaseImpl {
|
||||
public PsiJavaFileImpl(FileViewProvider file) {
|
||||
super(JavaStubElementTypes.JAVA_FILE, JavaStubElementTypes.JAVA_FILE, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@Override
|
||||
public FileType getFileType() {
|
||||
return JavaFileType.INSTANCE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiJavaModule getModuleDeclaration() {
|
||||
PsiElement element = getFirstChild();
|
||||
if (element instanceof PsiWhiteSpace || element instanceof PsiComment) {
|
||||
element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class);
|
||||
}
|
||||
return element instanceof PsiJavaModule ? (PsiJavaModule)element : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiJavaFile:" + getName();
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiJavaModuleImpl extends CompositePsiElement implements PsiJavaModule {
|
||||
public PsiJavaModuleImpl() {
|
||||
super(JavaElementType.MODULE);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiJavaModuleReference getNameElement() {
|
||||
return PsiTreeUtil.getChildOfType(this, PsiJavaModuleReference.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getModuleName() {
|
||||
PsiJavaModuleReference nameElement = getNameElement();
|
||||
return nameElement != null ? nameElement.getReferenceText() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitModule(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiJavaModule:" + getModuleName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiJavaModuleReferenceImpl extends CompositePsiElement implements PsiJavaModuleReference {
|
||||
public PsiJavaModuleReferenceImpl() {
|
||||
super(JavaElementType.MODULE_REFERENCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getReferenceText() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (PsiElement e = getFirstChild(); e != null; e = e.getNextSibling()) {
|
||||
if (!(e instanceof PsiWhiteSpace) && !(e instanceof PsiComment)) {
|
||||
sb.append(e.getText());
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitModuleReference(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiJavaModuleReference";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiProvidesStatement;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiProvidesStatementImpl extends CompositePsiElement implements PsiProvidesStatement {
|
||||
public PsiProvidesStatementImpl() {
|
||||
super(JavaElementType.PROVIDES_STATEMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitProvidesStatement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiProvidesStatement";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiRequiresStatement;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiRequiresStatementImpl extends CompositePsiElement implements PsiRequiresStatement {
|
||||
public PsiRequiresStatementImpl() {
|
||||
super(JavaElementType.REQUIRES_STATEMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitRequiresStatement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiRequiresStatement";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.psi.impl.source;
|
||||
|
||||
import com.intellij.psi.JavaElementVisitor;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiUsesStatement;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiUsesStatementImpl extends CompositePsiElement implements PsiUsesStatement {
|
||||
public PsiUsesStatementImpl() {
|
||||
super(JavaElementType.USES_STATEMENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitUsesStatement(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiUsesStatement";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -34,7 +34,8 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
IMPORT_KEYWORD, INSTANCEOF_KEYWORD, INT_KEYWORD, INTERFACE_KEYWORD, LONG_KEYWORD, NATIVE_KEYWORD, NEW_KEYWORD, PACKAGE_KEYWORD,
|
||||
PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, RETURN_KEYWORD, SHORT_KEYWORD, SUPER_KEYWORD, STATIC_KEYWORD, STRICTFP_KEYWORD,
|
||||
SWITCH_KEYWORD, SYNCHRONIZED_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, THROWS_KEYWORD, TRANSIENT_KEYWORD, TRY_KEYWORD, VOID_KEYWORD,
|
||||
VOLATILE_KEYWORD, WHILE_KEYWORD);
|
||||
VOLATILE_KEYWORD, WHILE_KEYWORD,
|
||||
MODULE_KEYWORD, REQUIRES_KEYWORD, EXPORTS_KEYWORD, USES_KEYWORD, PROVIDES_KEYWORD, TO_KEYWORD, WITH_KEYWORD);
|
||||
|
||||
TokenSet LITERAL_BIT_SET = TokenSet.create(TRUE_KEYWORD, FALSE_KEYWORD, NULL_KEYWORD);
|
||||
|
||||
|
||||
@@ -139,6 +139,13 @@ public interface JavaElementType {
|
||||
IElementType ANNOTATION_ARRAY_INITIALIZER = new JavaCompositeElementType("ANNOTATION_ARRAY_INITIALIZER", PsiArrayInitializerMemberValueImpl.class);
|
||||
IElementType RECEIVER_PARAMETER = new JavaCompositeElementType("RECEIVER", PsiReceiverParameterImpl.class);
|
||||
|
||||
IElementType MODULE = new JavaCompositeElementType("MODULE", PsiJavaModuleImpl.class);
|
||||
IElementType MODULE_REFERENCE = new JavaCompositeElementType("MODULE_NAME", PsiJavaModuleReferenceImpl.class);
|
||||
IElementType REQUIRES_STATEMENT = new JavaCompositeElementType("REQUIRES_STATEMENT", PsiRequiresStatementImpl.class);
|
||||
IElementType EXPORTS_STATEMENT = new JavaCompositeElementType("EXPORTS_STATEMENT", PsiExportsStatementImpl.class);
|
||||
IElementType USES_STATEMENT = new JavaCompositeElementType("USES_STATEMENT", PsiUsesStatementImpl.class);
|
||||
IElementType PROVIDES_STATEMENT = new JavaCompositeElementType("PROVIDES_STATEMENT", PsiProvidesStatementImpl.class);
|
||||
|
||||
class ICodeBlockElementType extends IErrorCounterReparseableElementType implements ICompositeElementType, ILightLazyParseableElementType {
|
||||
private ICodeBlockElementType() {
|
||||
super("CODE_BLOCK", JavaLanguage.INSTANCE);
|
||||
|
||||
+3
-2
@@ -91,6 +91,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
boolean doImportStatic;
|
||||
if (containingFile instanceof PsiJavaFile) {
|
||||
importList = ((PsiJavaFile)containingFile).getImportList();
|
||||
assert importList != null : containingFile;
|
||||
PsiImportStatementBase singleImportStatement = importList.findSingleImportStatement(staticName);
|
||||
doImportStatic = singleImportStatement == null;
|
||||
if (singleImportStatement instanceof PsiImportStaticStatement) {
|
||||
@@ -116,8 +117,8 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void bindToElementViaStaticImport(final PsiClass qualifierClass, final String staticName, final PsiImportList importList)
|
||||
throws IncorrectOperationException {
|
||||
public static void bindToElementViaStaticImport(PsiClass qualifierClass, String staticName, PsiImportList importList) throws IncorrectOperationException {
|
||||
assert importList != null;
|
||||
final String qualifiedName = qualifierClass.getQualifiedName();
|
||||
final List<PsiJavaCodeReferenceElement> refs = getImportsFromClass(importList, qualifiedName);
|
||||
if (refs.size() < JavaCodeStyleSettingsFacade.getInstance(qualifierClass.getProject()).getNamesCountToUseImportOnDemand()) {
|
||||
|
||||
@@ -336,6 +336,7 @@ expected.rbracket=']' expected
|
||||
expected.expression=Expression expected
|
||||
expected.semicolon=';' expected
|
||||
expected.class.reference=Class reference expected
|
||||
expected.package.reference=Package reference expected
|
||||
expected.lparen='(' expected
|
||||
expected.rparen=')' expected
|
||||
expected.eq='=' expected
|
||||
@@ -351,6 +352,7 @@ expected.type.parameter=Type parameter expected
|
||||
expected.comma=',' expected
|
||||
expected.comma.or.rparen=',' or ')' expected
|
||||
expected.colon=':' expected
|
||||
expected.dot='.' expected
|
||||
expected.type=Type expected
|
||||
expected.lbracket='[' expected
|
||||
expected.lparen.or.lbracket='(' or '[' expected
|
||||
@@ -365,6 +367,10 @@ expected.statement=Statement expected
|
||||
expected.while='while' expected
|
||||
expected.catch.or.finally='catch' or 'finally' expected
|
||||
expected.boolean.expression=Boolean expression expected
|
||||
expected.with='with' expected
|
||||
expected.module.declaration=Module declaration expected
|
||||
expected.module.statement=Module statement expected
|
||||
|
||||
error.cannot.resolve.class=Cannot resolve class ''{0}''
|
||||
error.cannot.resolve.class.or.package=Cannot resolve class or package ''{0}''
|
||||
expected.class.or.package=Expected class or package
|
||||
@@ -379,11 +385,17 @@ cannot.resolve.package=Cannot resolve package {0}
|
||||
override.not.allowed.in.interfaces=@Override is not allowed when implementing interface method
|
||||
wildcard.not.expected=Unexpected wildcard
|
||||
bound.not.expected=Unexpected bound
|
||||
declaration.not.allowed=Declaration not allowed here
|
||||
|
||||
underscore.identifier.warn=Use of '_' as an identifier might not be supported in releases after Java 8
|
||||
underscore.identifier.error=As of Java 9, '_' is a keyword, and may not be used as an identifier
|
||||
underscore.lambda.identifier=Use of '_' as a lambda parameter name is not allowed
|
||||
|
||||
module.file.wrong.name=Module declaration should be in a file named 'module-info.java'
|
||||
module.illegal.name=Illegal module name
|
||||
module.file.duplicate=Multiple module declarations
|
||||
module.file.wrong.location=Module declaration should be located in a module's source root
|
||||
|
||||
feature.generics=Generics
|
||||
feature.annotations=Annotations
|
||||
feature.static.imports=Static imports
|
||||
@@ -401,5 +413,5 @@ feature.lambda.expressions=Lambda expressions
|
||||
feature.type.annotations=Type annotations
|
||||
feature.type.receivers=Receiver parameters
|
||||
feature.try.with.resources.refs=Resource references
|
||||
feature.modules=Modules
|
||||
insufficient.language.level={0} are not supported at this language level
|
||||
declaration.not.allowed=Declaration not allowed here
|
||||
|
||||
+7
-1
@@ -20,6 +20,7 @@ import com.intellij.navigation.ColoredItemPresentation;
|
||||
import com.intellij.navigation.LocationPresentation;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -104,7 +105,12 @@ public abstract class JavaClassTreeElementBase<Value extends PsiElement> extends
|
||||
|
||||
@Override
|
||||
public TextAttributesKey getTextAttributesKey() {
|
||||
return isDeprecated() ? CodeInsightColors.DEPRECATED_ATTRIBUTES : null;
|
||||
try {
|
||||
return isDeprecated() ? CodeInsightColors.DEPRECATED_ATTRIBUTES : null;
|
||||
}
|
||||
catch (IndexNotReadyException ignore) {
|
||||
return null; // do not show deprecated elements while indexing
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDeprecated(){
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@ public class Main {
|
||||
protected Object obj = null;
|
||||
private long e = 4;
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ class C implements A {
|
||||
|
||||
interface A {
|
||||
A a = new C(<error descr="'A.this' cannot be referenced from a static context">this</error>);
|
||||
A a1 = new C(<error descr="Cannot find symbol variable this">this</error>){};
|
||||
A a1 = new C(<error descr="'A.this' cannot be referenced from a static context">this</error>){};
|
||||
|
||||
class B {
|
||||
A foo() {
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class A {
|
||||
public A(Object o) {
|
||||
}
|
||||
}
|
||||
|
||||
class B {}
|
||||
|
||||
class C extends B {
|
||||
static {
|
||||
A a = new A(<error descr="'C.this' cannot be referenced from a static context">this</error>) {};
|
||||
A a1 = new A(<error descr="'C.super' cannot be referenced from a static context">super</error>.clone()) {};
|
||||
}
|
||||
|
||||
{
|
||||
A a = new A(this);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user