mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.resolve.reference.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.encoding.EncodingReference;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.manipulators.StringLiteralManipulator;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.literalExpression;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiMethod;
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaCharsetReferenceContributor extends PsiReferenceContributor {
|
||||
@Override
|
||||
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
|
||||
registrar.registerReferenceProvider(
|
||||
literalExpression().methodCallParameter(
|
||||
0, psiMethod().withName(string().oneOf("forName", "isSupported")).inClass(Charset.class.getName())),
|
||||
new PsiReferenceProvider() {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||
PsiLiteralExpression literal = (PsiLiteralExpression)element;
|
||||
Object value = literal.getValue();
|
||||
if (value instanceof String) {
|
||||
return new PsiReference[]{new EncodingReference(element, (String)value, StringLiteralManipulator.getValueRange(literal))};
|
||||
}
|
||||
return PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public final class FileAttributes {
|
||||
{
|
||||
Charset.forName("utf<caret>")
|
||||
}
|
||||
}
|
||||
+6
@@ -1216,6 +1216,12 @@ class XInternalError {}
|
||||
|
||||
public void testConstantInAnno() { doTest() }
|
||||
|
||||
public void testCharsetName() {
|
||||
myFixture.addClass("package java.nio.charset; public class Charset { public static Charset forName(String s) {} }")
|
||||
configureByTestName()
|
||||
assert myFixture.lookupElementStrings.contains('UTF-8')
|
||||
}
|
||||
|
||||
public void testInnerClassInExtendsGenerics() {
|
||||
def text = "package bar; class Foo extends List<Inne<caret>> { public static class Inner {} }"
|
||||
myFixture.configureFromExistingVirtualFile(myFixture.addClass(text).containingFile.virtualFile)
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.encoding;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class EncodingReference implements PsiReference {
|
||||
private final PsiElement myElement;
|
||||
|
||||
private final String myCharsetName;
|
||||
private final TextRange myRangeInElement;
|
||||
|
||||
public EncodingReference(PsiElement element, final String charsetName, final TextRange rangeInElement) {
|
||||
myElement = element;
|
||||
myCharsetName = charsetName;
|
||||
myRangeInElement = rangeInElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return myElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return myRangeInElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement resolve() {
|
||||
return CharsetToolkit.forName(myCharsetName) == null ? null : myElement;
|
||||
//if (ApplicationManager.getApplication().isUnitTestMode()) return myValue; // tests do not have full JDK
|
||||
//String fqn = charset.getClass().getName();
|
||||
//return myValue.getManager().findClass(fqn, GlobalSearchScope.allScope(myValue.getProject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
return myCharsetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
Charset[] charsets = CharsetToolkit.getAvailableCharsets();
|
||||
List<LookupElement> suggestions = new ArrayList<LookupElement>(charsets.length);
|
||||
for (Charset charset : charsets) {
|
||||
suggestions.add(LookupElementBuilder.create(charset.name()).withCaseSensitivity(false));
|
||||
}
|
||||
return suggestions.toArray(new LookupElement[suggestions.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,15 +36,14 @@ import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.LogicalRoot;
|
||||
import com.intellij.util.LogicalRootsManager;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -53,6 +52,8 @@ import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexey
|
||||
@@ -68,10 +69,20 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
boolean plural = false;
|
||||
boolean enabled;
|
||||
|
||||
DataContext dataContext = e.getDataContext();
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
boolean enabled = (editor != null && FileDocumentManager.getInstance().getFile(editor.getDocument()) != null) ||
|
||||
getElementToCopy(editor, dataContext) != null;
|
||||
if (editor != null && FileDocumentManager.getInstance().getFile(editor.getDocument()) != null) {
|
||||
enabled = true;
|
||||
}
|
||||
else {
|
||||
List<PsiElement> elements = getElementsToCopy(editor, dataContext);
|
||||
enabled = !elements.isEmpty();
|
||||
plural = elements.size() > 1;
|
||||
}
|
||||
|
||||
e.getPresentation().setEnabled(enabled);
|
||||
if (ActionPlaces.isPopupPlace(e.getPlace())) {
|
||||
e.getPresentation().setVisible(enabled);
|
||||
@@ -79,6 +90,7 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
else {
|
||||
e.getPresentation().setVisible(true);
|
||||
}
|
||||
e.getPresentation().setText(plural ? "Cop&y References" : "Cop&y Reference");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,9 +98,9 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
DataContext dataContext = e.getDataContext();
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
PsiElement element = getElementToCopy(editor, dataContext);
|
||||
List<PsiElement> elements = getElementsToCopy(editor, dataContext);
|
||||
|
||||
if (!doCopy(element, project, editor) && editor != null && project != null) {
|
||||
if (!doCopy(elements, project, editor) && editor != null && project != null) {
|
||||
Document document = editor.getDocument();
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
|
||||
if (file != null) {
|
||||
@@ -102,45 +114,54 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
HighlightManager highlightManager = HighlightManager.getInstance(project);
|
||||
EditorColorsManager manager = EditorColorsManager.getInstance();
|
||||
TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
|
||||
if (element != null && editor != null && project != null) {
|
||||
PsiElement nameIdentifier = IdentifierUtil.getNameIdentifier(element);
|
||||
if (elements.size() == 1 && editor != null && project != null) {
|
||||
PsiElement nameIdentifier = IdentifierUtil.getNameIdentifier(elements.get(0));
|
||||
if (nameIdentifier != null) {
|
||||
highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{nameIdentifier}, attributes, true, null);
|
||||
} else {
|
||||
PsiReference reference = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
|
||||
if (reference != null) {
|
||||
highlightManager.addOccurrenceHighlights(editor, new PsiReference[]{reference}, attributes, true, null);
|
||||
} else if (element != PsiDocumentManager.getInstance(project).getCachedPsiFile(editor.getDocument())) {
|
||||
highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{element}, attributes, true, null);
|
||||
} else if (elements != PsiDocumentManager.getInstance(project).getCachedPsiFile(editor.getDocument())) {
|
||||
highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{elements.get(0)}, attributes, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement getElementToCopy(@Nullable final Editor editor, final DataContext dataContext) {
|
||||
PsiElement element = null;
|
||||
@NotNull
|
||||
private static List<PsiElement> getElementsToCopy(@Nullable final Editor editor, final DataContext dataContext) {
|
||||
List<PsiElement> elements = ContainerUtil.newArrayList();
|
||||
if (editor != null) {
|
||||
PsiReference reference = TargetElementUtilBase.findReference(editor);
|
||||
if (reference != null) {
|
||||
element = reference.getElement();
|
||||
ContainerUtil.addIfNotNull(elements, reference.getElement());
|
||||
}
|
||||
}
|
||||
|
||||
if (element == null) {
|
||||
element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
|
||||
}
|
||||
if (element == null && editor == null) {
|
||||
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(dataContext);
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (virtualFile != null && project != null) {
|
||||
element = PsiManager.getInstance(project).findFile(virtualFile);
|
||||
}
|
||||
}
|
||||
if (element instanceof PsiFile && !((PsiFile)element).getViewProvider().isPhysical()) {
|
||||
return null;
|
||||
if (elements.isEmpty()) {
|
||||
ContainerUtil.addIfNotNull(elements, CommonDataKeys.PSI_ELEMENT.getData(dataContext));
|
||||
}
|
||||
|
||||
if (elements.isEmpty() && editor == null) {
|
||||
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
|
||||
if (project != null && files != null) {
|
||||
for (VirtualFile file : files) {
|
||||
ContainerUtil.addIfNotNull(elements, PsiManager.getInstance(project).findFile(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ContainerUtil.mapNotNull(elements, new Function<PsiElement, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(PsiElement element) {
|
||||
return element instanceof PsiFile && !((PsiFile)element).getViewProvider().isPhysical() ? null : adjustElement(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiElement adjustElement(PsiElement element) {
|
||||
for (QualifiedNameProvider provider : Extensions.getExtensions(QualifiedNameProvider.EP_NAME)) {
|
||||
PsiElement adjustedElement = provider.adjustElementToCopy(element);
|
||||
if (adjustedElement != null) return adjustedElement;
|
||||
@@ -149,16 +170,25 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
}
|
||||
|
||||
public static boolean doCopy(final PsiElement element, final Project project) {
|
||||
return doCopy(element, project, null);
|
||||
return doCopy(Arrays.asList(element), project, null);
|
||||
}
|
||||
|
||||
private static boolean doCopy(final PsiElement element, @Nullable final Project project, @Nullable Editor editor) {
|
||||
String fqn = elementToFqn(element, editor);
|
||||
if (fqn == null) return false;
|
||||
private static boolean doCopy(List<PsiElement> elements, @Nullable final Project project, @Nullable Editor editor) {
|
||||
if (elements.isEmpty()) return false;
|
||||
|
||||
CopyPasteManager.getInstance().setContents(new MyTransferable(fqn));
|
||||
List<String> fqns = ContainerUtil.newArrayList();
|
||||
for (PsiElement element : elements) {
|
||||
String fqn = elementToFqn(element, editor);
|
||||
if (fqn == null) return false;
|
||||
|
||||
setStatusBarText(project, IdeBundle.message("message.reference.to.fqn.has.been.copied", fqn));
|
||||
fqns.add(fqn);
|
||||
}
|
||||
|
||||
String toCopy = StringUtil.join(fqns, "\n");
|
||||
|
||||
CopyPasteManager.getInstance().setContents(new MyTransferable(toCopy));
|
||||
|
||||
setStatusBarText(project, IdeBundle.message("message.reference.to.fqn.has.been.copied", toCopy));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -199,12 +229,12 @@ public class CopyReferenceAction extends DumbAwareAction {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String elementToFqn(final PsiElement element) {
|
||||
public static String elementToFqn(@Nullable final PsiElement element) {
|
||||
return elementToFqn(element, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String elementToFqn(final PsiElement element, @Nullable Editor editor) {
|
||||
private static String elementToFqn(@Nullable final PsiElement element, @Nullable Editor editor) {
|
||||
String result = getQualifiedNameFromProviders(element);
|
||||
if (result != null) return result;
|
||||
|
||||
|
||||
@@ -1471,6 +1471,7 @@
|
||||
implementationClass="com.intellij.psi.impl.JavaRegExpHost"/>
|
||||
|
||||
<psi.referenceContributor language="JAVA" implementation="com.intellij.psi.impl.source.resolve.reference.impl.JavaReflectionReferenceContributor"/>
|
||||
<psi.referenceContributor language="JAVA" implementation="com.intellij.psi.impl.source.resolve.reference.impl.JavaCharsetReferenceContributor"/>
|
||||
|
||||
<writingAccessProvider implementation="com.intellij.refactoring.util.ClsElementWritingAccessProvider"/>
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ cdata
|
||||
cglib
|
||||
changelist
|
||||
charset
|
||||
charsets
|
||||
checkbox
|
||||
checkboxes
|
||||
checksum
|
||||
|
||||
+2
-75
@@ -17,57 +17,21 @@ package com.intellij.codeInsight.daemon.impl.analysis.encoding;
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
|
||||
import com.intellij.codeInsight.daemon.XmlErrorMessages;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class XmlEncodingReference implements PsiReference, EmptyResolveMessageProvider, Comparable<XmlEncodingReference> {
|
||||
private final XmlAttributeValue myValue;
|
||||
|
||||
private final String myCharsetName;
|
||||
private final TextRange myRangeInElement;
|
||||
public class XmlEncodingReference extends EncodingReference implements EmptyResolveMessageProvider, Comparable<XmlEncodingReference> {
|
||||
private final int myPriority;
|
||||
|
||||
public XmlEncodingReference(XmlAttributeValue value, final String charsetName, final TextRange rangeInElement, int priority) {
|
||||
myValue = value;
|
||||
myCharsetName = charsetName;
|
||||
myRangeInElement = rangeInElement;
|
||||
super(value, charsetName, rangeInElement);
|
||||
myPriority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return myRangeInElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement resolve() {
|
||||
return CharsetToolkit.forName(myCharsetName) == null ? null : myValue;
|
||||
//if (ApplicationManager.getApplication().isUnitTestMode()) return myValue; // tests do not have full JDK
|
||||
//String fqn = charset.getClass().getName();
|
||||
//return myValue.getManager().findClass(fqn, GlobalSearchScope.allScope(myValue.getProject()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getUnresolvedMessagePattern() {
|
||||
@@ -75,43 +39,6 @@ public class XmlEncodingReference implements PsiReference, EmptyResolveMessagePr
|
||||
return XmlErrorMessages.message("unknown.encoding.0");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
return myCharsetName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
Charset[] charsets = CharsetToolkit.getAvailableCharsets();
|
||||
List<LookupElement> suggestions = new ArrayList<LookupElement>(charsets.length);
|
||||
for (Charset charset : charsets) {
|
||||
suggestions.add(LookupElementBuilder.create(charset.name()).withCaseSensitivity(false));
|
||||
}
|
||||
return suggestions.toArray(new LookupElement[suggestions.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull XmlEncodingReference ref) {
|
||||
return myPriority - ref.myPriority;
|
||||
|
||||
Reference in New Issue
Block a user