Added default implementation for ExternalAnnotationsProvider to be used in compiler.
This commit is contained in:
@@ -33,6 +33,8 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.extAnnotations.CoreAnnotationsProvider;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider;
|
||||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
|
|
||||||
@@ -91,6 +93,9 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
|
|||||||
addLibraryRoot(root);
|
addLibraryRoot(root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExternalAnnotationsProvider.setInstance(new CoreAnnotationsProvider());
|
||||||
|
|
||||||
if (compilerSpecialMode.includeKotlinRuntime()) {
|
if (compilerSpecialMode.includeKotlinRuntime()) {
|
||||||
addToClasspath(compilerDependencies.getRuntimeJar());
|
addToClasspath(compilerDependencies.getRuntimeJar());
|
||||||
}
|
}
|
||||||
|
|||||||
+203
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Comparing;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
|
import com.intellij.util.StringBuilderSpinAllocator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied from IDEA.
|
||||||
|
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||||
|
* @author Evgeny Gerashchenko
|
||||||
|
* @since 6/26/12
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class ClassUtil {
|
||||||
|
private ClassUtil() {}
|
||||||
|
|
||||||
|
public static void formatClassName(@NotNull final PsiClass aClass, final StringBuilder buf) {
|
||||||
|
final String qName = aClass.getQualifiedName();
|
||||||
|
if (qName != null) {
|
||||||
|
buf.append(qName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final PsiClass parentClass = getContainerClass(aClass);
|
||||||
|
if (parentClass != null) {
|
||||||
|
formatClassName(parentClass, buf);
|
||||||
|
buf.append("$");
|
||||||
|
buf.append(getNonQualifiedClassIdx(aClass));
|
||||||
|
final String name = aClass.getName();
|
||||||
|
if (name != null) {
|
||||||
|
buf.append(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static PsiClass getContainerClass(final PsiClass aClass) {
|
||||||
|
PsiElement parent = aClass.getContext();
|
||||||
|
while (parent != null && !(parent instanceof PsiClass)) {
|
||||||
|
parent = parent.getContext();
|
||||||
|
}
|
||||||
|
return (PsiClass)parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getNonQualifiedClassIdx(@NotNull final PsiClass psiClass) {
|
||||||
|
final int[] result = {-1};
|
||||||
|
final PsiClass containingClass = getContainerClass(psiClass);
|
||||||
|
if (containingClass != null) {
|
||||||
|
containingClass.accept(new JavaRecursiveElementVisitor() {
|
||||||
|
private int myCurrentIdx = 0;
|
||||||
|
|
||||||
|
@Override public void visitElement(PsiElement element) {
|
||||||
|
if (result[0] == -1) {
|
||||||
|
super.visitElement(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void visitClass(PsiClass aClass) {
|
||||||
|
super.visitClass(aClass);
|
||||||
|
if (aClass.getQualifiedName() == null) {
|
||||||
|
myCurrentIdx++;
|
||||||
|
if (psiClass == aClass) {
|
||||||
|
result[0] = myCurrentIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PsiClass findNonQualifiedClassByIndex(final String indexName, @NotNull final PsiClass containingClass,
|
||||||
|
final boolean jvmCompatible) {
|
||||||
|
String prefix = getDigitPrefix(indexName);
|
||||||
|
final int idx = prefix.length() > 0 ? Integer.parseInt(prefix) : -1;
|
||||||
|
final String name = prefix.length() < indexName.length() ? indexName.substring(prefix.length()) : null;
|
||||||
|
final PsiClass[] result = new PsiClass[1];
|
||||||
|
containingClass.accept(new JavaRecursiveElementVisitor() {
|
||||||
|
private int myCurrentIdx = 0;
|
||||||
|
|
||||||
|
@Override public void visitElement(PsiElement element) {
|
||||||
|
if (result[0] == null) {
|
||||||
|
super.visitElement(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void visitClass(PsiClass aClass) {
|
||||||
|
if (!jvmCompatible) {
|
||||||
|
super.visitClass(aClass);
|
||||||
|
if (aClass.getQualifiedName() == null) {
|
||||||
|
myCurrentIdx++;
|
||||||
|
if (myCurrentIdx == idx && Comparing.strEqual(name, aClass.getName())) {
|
||||||
|
result[0] = aClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (aClass == containingClass) {
|
||||||
|
super.visitClass(aClass);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Comparing.strEqual(name, aClass.getName())) {
|
||||||
|
myCurrentIdx++;
|
||||||
|
if (myCurrentIdx == idx || idx == -1) {
|
||||||
|
result[0] = aClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void visitTypeParameter(final PsiTypeParameter classParameter) {
|
||||||
|
if (!jvmCompatible) {
|
||||||
|
super.visitTypeParameter(classParameter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
visitElement(classParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDigitPrefix(final String indexName) {
|
||||||
|
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < indexName.length(); i++) {
|
||||||
|
final char c = indexName.charAt(i);
|
||||||
|
if (Character.isDigit(c)) {
|
||||||
|
builder.append(c);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
StringBuilderSpinAllocator.dispose(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static PsiClass findPsiClass(final PsiManager psiManager,
|
||||||
|
String externalName,
|
||||||
|
PsiClass psiClass,
|
||||||
|
boolean jvmCompatible) {
|
||||||
|
return findPsiClass(psiManager, externalName, psiClass, jvmCompatible, GlobalSearchScope.allScope(psiManager.getProject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static PsiClass findPsiClass(final PsiManager psiManager,
|
||||||
|
String externalName,
|
||||||
|
@Nullable PsiClass psiClass,
|
||||||
|
boolean jvmCompatible,
|
||||||
|
final GlobalSearchScope scope) {
|
||||||
|
final int topIdx = externalName.indexOf('$');
|
||||||
|
if (topIdx > -1) {
|
||||||
|
if (psiClass == null) {
|
||||||
|
psiClass = JavaPsiFacade.getInstance(psiManager.getProject())
|
||||||
|
.findClass(externalName.substring(0, topIdx), scope);
|
||||||
|
}
|
||||||
|
if (psiClass == null) return null;
|
||||||
|
externalName = externalName.substring(topIdx + 1);
|
||||||
|
return findSubclass(psiManager, externalName, psiClass, jvmCompatible);
|
||||||
|
} else {
|
||||||
|
return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(externalName, scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static PsiClass findSubclass(final PsiManager psiManager,
|
||||||
|
final String externalName,
|
||||||
|
final PsiClass psiClass,
|
||||||
|
final boolean jvmCompatible) {
|
||||||
|
final int nextIdx = externalName.indexOf('$');
|
||||||
|
if (nextIdx > -1) {
|
||||||
|
final PsiClass anonymousClass = findNonQualifiedClassByIndex(externalName.substring(0, nextIdx), psiClass, jvmCompatible);
|
||||||
|
if (anonymousClass == null) return null;
|
||||||
|
return findPsiClass(psiManager, externalName.substring(nextIdx), anonymousClass, jvmCompatible);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return findNonQualifiedClassByIndex(externalName, psiClass, jvmCompatible);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+246
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||||
|
|
||||||
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.Comparing;
|
||||||
|
import com.intellij.openapi.util.JDOMUtil;
|
||||||
|
import com.intellij.openapi.util.io.StreamUtil;
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import com.intellij.util.StringBuilderSpinAllocator;
|
||||||
|
import com.intellij.util.containers.ConcurrentWeakHashMap;
|
||||||
|
import com.intellij.util.containers.ConcurrentWeakValueHashMap;
|
||||||
|
import org.jdom.Document;
|
||||||
|
import org.jdom.Element;
|
||||||
|
import org.jdom.JDOMException;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied from IDEA.
|
||||||
|
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||||
|
* @author Evgeny Gerashchenko
|
||||||
|
* @since 6/26/12
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class CoreAnnotationsProvider extends ExternalAnnotationsProvider {
|
||||||
|
private static final Logger LOG = Logger.getInstance("#" + CoreAnnotationsProvider.class.getName());
|
||||||
|
@NotNull private static final List<PsiFile> NULL = new ArrayList<PsiFile>();
|
||||||
|
@NotNull private final ConcurrentMap<String, List<PsiFile>>
|
||||||
|
myExternalAnnotations = new ConcurrentWeakValueHashMap<String, List<PsiFile>>();
|
||||||
|
|
||||||
|
private List<VirtualFile> externalAnnotationsRoots = new ArrayList<VirtualFile>();
|
||||||
|
|
||||||
|
public CoreAnnotationsProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getExternalName(PsiModifierListOwner listOwner, boolean showParamName) {
|
||||||
|
return PsiFormatUtil.getExternalName(listOwner, showParamName, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String getFQN(String packageName, @Nullable VirtualFile virtualFile) {
|
||||||
|
if (virtualFile == null) return null;
|
||||||
|
return StringUtil.getQualifiedName(packageName, virtualFile.getNameWithoutExtension());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected static String getNormalizedExternalName(@NotNull PsiModifierListOwner owner) {
|
||||||
|
String externalName = getExternalName(owner, true);
|
||||||
|
if (externalName != null) {
|
||||||
|
if (owner instanceof PsiParameter && owner.getParent() instanceof PsiParameterList) {
|
||||||
|
final PsiMethod method = PsiTreeUtil.getParentOfType(owner, PsiMethod.class);
|
||||||
|
if (method != null) {
|
||||||
|
externalName =
|
||||||
|
externalName.substring(0, externalName.lastIndexOf(' ') + 1) + method.getParameterList().getParameterIndex((PsiParameter)owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int idx = externalName.indexOf('(');
|
||||||
|
if (idx == -1) return externalName;
|
||||||
|
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||||
|
try {
|
||||||
|
final int rightIdx = externalName.indexOf(')');
|
||||||
|
final String[] params = externalName.substring(idx + 1, rightIdx).split(",");
|
||||||
|
buf.append(externalName.substring(0, idx + 1));
|
||||||
|
for (String param : params) {
|
||||||
|
param = param.trim();
|
||||||
|
final int spaceIdx = param.indexOf(' ');
|
||||||
|
buf.append(spaceIdx > -1 ? param.substring(0, spaceIdx) : param).append(", ");
|
||||||
|
}
|
||||||
|
return StringUtil.trimEnd(buf.toString(), ", ") + externalName.substring(rightIdx);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
StringBuilderSpinAllocator.dispose(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return externalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public PsiAnnotation findExternalAnnotation(@NotNull Project project, @NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
|
||||||
|
return collectExternalAnnotations(listOwner).get(annotationFQN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public PsiAnnotation[] findExternalAnnotations(@NotNull Project project, @NotNull final PsiModifierListOwner listOwner) {
|
||||||
|
final Map<String, PsiAnnotation> result = collectExternalAnnotations(listOwner);
|
||||||
|
return result.isEmpty() ? null : result.values().toArray(new PsiAnnotation[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<PsiModifierListOwner, Map<String, PsiAnnotation>> cache = new ConcurrentWeakHashMap<PsiModifierListOwner, Map<String, PsiAnnotation>>();
|
||||||
|
@NotNull
|
||||||
|
private Map<String, PsiAnnotation> collectExternalAnnotations(@NotNull final PsiModifierListOwner listOwner) {
|
||||||
|
Map<String, PsiAnnotation> map = cache.get(listOwner);
|
||||||
|
if (map == null) {
|
||||||
|
map = doCollect(listOwner);
|
||||||
|
cache.put(listOwner, map);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addExternalAnnotationsRoot(VirtualFile externalAnnotationsRoot) {
|
||||||
|
externalAnnotationsRoots.add(externalAnnotationsRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PsiAnnotation> doCollect(@NotNull PsiModifierListOwner listOwner) {
|
||||||
|
final List<PsiFile> files = findExternalAnnotationsFiles(listOwner);
|
||||||
|
if (files == null) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
final Map<String, PsiAnnotation> result = new HashMap<String, PsiAnnotation>();
|
||||||
|
for (PsiFile file : files) {
|
||||||
|
if (!file.isValid()) continue;
|
||||||
|
final Document document;
|
||||||
|
try {
|
||||||
|
document = JDOMUtil.loadDocument(escapeAttributes(StreamUtil.readText(file.getVirtualFile().getInputStream())));
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
|
||||||
|
LOG.error(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
catch (JDOMException e) {
|
||||||
|
LOG.error(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (document == null) continue;
|
||||||
|
final Element rootElement = document.getRootElement();
|
||||||
|
if (rootElement == null) continue;
|
||||||
|
final String externalName = getExternalName(listOwner, false);
|
||||||
|
final String oldExternalName = getNormalizedExternalName(listOwner);
|
||||||
|
//noinspection unchecked
|
||||||
|
for (final Element element : (List<Element>) rootElement.getChildren()) {
|
||||||
|
final String className = element.getAttributeValue("name");
|
||||||
|
if (!Comparing.strEqual(className, externalName) && !Comparing.strEqual(className, oldExternalName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//noinspection unchecked
|
||||||
|
for (Element annotationElement : (List<Element>) element.getChildren()) {
|
||||||
|
final String annotationFQN = annotationElement.getAttributeValue("name");
|
||||||
|
final StringBuilder buf = new StringBuilder();
|
||||||
|
//noinspection unchecked
|
||||||
|
for (Element annotationParameter : (List<Element>) annotationElement.getChildren()) {
|
||||||
|
buf.append(",");
|
||||||
|
final String nameValue = annotationParameter.getAttributeValue("name");
|
||||||
|
if (nameValue != null) {
|
||||||
|
buf.append(nameValue).append("=");
|
||||||
|
}
|
||||||
|
buf.append(annotationParameter.getAttributeValue("val"));
|
||||||
|
}
|
||||||
|
final String annotationText =
|
||||||
|
"@" + annotationFQN + (buf.length() > 0 ? "(" + StringUtil.trimStart(buf.toString(), ",") + ")" : "");
|
||||||
|
try {
|
||||||
|
result.put(annotationFQN,
|
||||||
|
JavaPsiFacade.getInstance(listOwner.getProject()).getElementFactory().createAnnotationFromText(
|
||||||
|
annotationText, null));
|
||||||
|
}
|
||||||
|
catch (IncorrectOperationException e) {
|
||||||
|
LOG.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private List<PsiFile> findExternalAnnotationsFiles(@NotNull PsiModifierListOwner listOwner) {
|
||||||
|
final PsiFile containingFile = listOwner.getContainingFile();
|
||||||
|
if (!(containingFile instanceof PsiJavaFile)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final PsiJavaFile javaFile = (PsiJavaFile)containingFile;
|
||||||
|
final String packageName = javaFile.getPackageName();
|
||||||
|
final VirtualFile virtualFile = containingFile.getVirtualFile();
|
||||||
|
String fqn = getFQN(packageName, virtualFile);
|
||||||
|
if (fqn == null) return null;
|
||||||
|
final List<PsiFile> files = myExternalAnnotations.get(fqn);
|
||||||
|
if (files == NULL) return null;
|
||||||
|
if (files != null) {
|
||||||
|
for (Iterator<PsiFile> it = files.iterator(); it.hasNext();) {
|
||||||
|
if (!it.next().isValid()) it.remove();
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virtualFile == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PsiFile> possibleAnnotationsXmls = new ArrayList<PsiFile>();
|
||||||
|
for (VirtualFile root : externalAnnotationsRoots) {
|
||||||
|
final VirtualFile ext = root.findFileByRelativePath(packageName.replace(".", "/") + "/" + "annotations.xml");
|
||||||
|
if (ext == null) continue;
|
||||||
|
final PsiFile psiFile = listOwner.getManager().findFile(ext);
|
||||||
|
possibleAnnotationsXmls.add(psiFile);
|
||||||
|
}
|
||||||
|
if (!possibleAnnotationsXmls.isEmpty()) {
|
||||||
|
myExternalAnnotations.put(fqn, possibleAnnotationsXmls);
|
||||||
|
return possibleAnnotationsXmls;
|
||||||
|
}
|
||||||
|
myExternalAnnotations.put(fqn, NULL);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method is used for legacy reasons.
|
||||||
|
// Old external annotations sometimes are bad XML: they have "<" and ">" characters in attributes values. To prevent SAX parser from
|
||||||
|
// failing, we escape attributes values.
|
||||||
|
@NotNull
|
||||||
|
private static String escapeAttributes(@NotNull String invalidXml) {
|
||||||
|
// We assume that XML has single- and double-quote characters only for attribute values, therefore we don't any complex parsing,
|
||||||
|
// just split by ['"] regexp instead
|
||||||
|
String[] split = invalidXml.split("[\"\']");
|
||||||
|
assert split.length % 2 == 1;
|
||||||
|
for (int i = 1; i < split.length; i += 2) {
|
||||||
|
split[i] = split[i].replace("<", "<").replace(">", ">");
|
||||||
|
}
|
||||||
|
return StringUtil.join(split, "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
+235
@@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User: anna
|
||||||
|
* Date: 28-Oct-2008
|
||||||
|
*/
|
||||||
|
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||||
|
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.util.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied from IDEA.
|
||||||
|
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||||
|
* @author Evgeny Gerashchenko
|
||||||
|
* @since 6/26/12
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class PsiExpressionTrimRenderer extends JavaRecursiveElementWalkingVisitor {
|
||||||
|
private final StringBuilder myBuf;
|
||||||
|
|
||||||
|
public PsiExpressionTrimRenderer(final StringBuilder buf) {
|
||||||
|
myBuf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExpression(final PsiExpression expression) {
|
||||||
|
myBuf.append(expression.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInstanceOfExpression(final PsiInstanceOfExpression expression) {
|
||||||
|
expression.getOperand().accept(this);
|
||||||
|
myBuf.append(" ").append(PsiKeyword.INSTANCEOF).append(" ");
|
||||||
|
final PsiTypeElement checkType = expression.getCheckType();
|
||||||
|
if (checkType != null) {
|
||||||
|
myBuf.append(checkType.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitParenthesizedExpression(final PsiParenthesizedExpression expression) {
|
||||||
|
myBuf.append("(");
|
||||||
|
final PsiExpression expr = expression.getExpression();
|
||||||
|
if (expr != null) {
|
||||||
|
expr.accept(this);
|
||||||
|
}
|
||||||
|
myBuf.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeCastExpression(final PsiTypeCastExpression expression) {
|
||||||
|
final PsiTypeElement castType = expression.getCastType();
|
||||||
|
if (castType != null) {
|
||||||
|
myBuf.append("(").append(castType.getText()).append(")");
|
||||||
|
}
|
||||||
|
final PsiExpression operand = expression.getOperand();
|
||||||
|
if (operand != null) {
|
||||||
|
operand.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) {
|
||||||
|
expression.getArrayExpression().accept(this);
|
||||||
|
myBuf.append("[");
|
||||||
|
final PsiExpression indexExpression = expression.getIndexExpression();
|
||||||
|
if (indexExpression != null) {
|
||||||
|
indexExpression.accept(this);
|
||||||
|
}
|
||||||
|
myBuf.append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPrefixExpression(final PsiPrefixExpression expression) {
|
||||||
|
myBuf.append(expression.getOperationSign().getText());
|
||||||
|
final PsiExpression operand = expression.getOperand();
|
||||||
|
if (operand != null) {
|
||||||
|
operand.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPostfixExpression(final PsiPostfixExpression expression) {
|
||||||
|
expression.getOperand().accept(this);
|
||||||
|
myBuf.append(expression.getOperationSign().getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitPolyadicExpression(PsiPolyadicExpression expression) {
|
||||||
|
PsiExpression[] operands = expression.getOperands();
|
||||||
|
for (int i = 0; i < operands.length; i++) {
|
||||||
|
PsiExpression operand = operands[i];
|
||||||
|
if (i != 0) {
|
||||||
|
PsiJavaToken token = expression.getTokenBeforeOperand(operand);
|
||||||
|
myBuf.append(" ").append(token.getText()).append(" ");
|
||||||
|
}
|
||||||
|
operand.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitConditionalExpression(final PsiConditionalExpression expression) {
|
||||||
|
expression.getCondition().accept(this);
|
||||||
|
|
||||||
|
myBuf.append(" ? ");
|
||||||
|
final PsiExpression thenExpression = expression.getThenExpression();
|
||||||
|
if (thenExpression != null) {
|
||||||
|
thenExpression.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
myBuf.append(" : ");
|
||||||
|
final PsiExpression elseExpression = expression.getElseExpression();
|
||||||
|
if (elseExpression != null) {
|
||||||
|
elseExpression.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitAssignmentExpression(final PsiAssignmentExpression expression) {
|
||||||
|
expression.getLExpression().accept(this);
|
||||||
|
myBuf.append(expression.getOperationSign().getText());
|
||||||
|
final PsiExpression rExpression = expression.getRExpression();
|
||||||
|
if (rExpression != null) {
|
||||||
|
rExpression.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReferenceExpression(final PsiReferenceExpression expr) {
|
||||||
|
final PsiExpression qualifierExpression = expr.getQualifierExpression();
|
||||||
|
if (qualifierExpression != null) {
|
||||||
|
qualifierExpression.accept(this);
|
||||||
|
myBuf.append(".");
|
||||||
|
}
|
||||||
|
myBuf.append(expr.getReferenceName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitMethodCallExpression(final PsiMethodCallExpression expr) {
|
||||||
|
expr.getMethodExpression().accept(this);
|
||||||
|
expr.getArgumentList().accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitArrayInitializerExpression(final PsiArrayInitializerExpression expression) {
|
||||||
|
myBuf.append("{");
|
||||||
|
boolean first = true;
|
||||||
|
for (PsiExpression expr : expression.getInitializers()) {
|
||||||
|
if (!first) {
|
||||||
|
myBuf.append(", ");
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
expr.accept(this);
|
||||||
|
}
|
||||||
|
myBuf.append("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExpressionList(final PsiExpressionList list) {
|
||||||
|
final PsiExpression[] args = list.getExpressions();
|
||||||
|
if (args.length > 0) {
|
||||||
|
myBuf.append("(...)");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myBuf.append("()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewExpression(final PsiNewExpression expr) {
|
||||||
|
final PsiAnonymousClass anonymousClass = expr.getAnonymousClass();
|
||||||
|
|
||||||
|
final PsiExpressionList argumentList = expr.getArgumentList();
|
||||||
|
|
||||||
|
if (anonymousClass != null) {
|
||||||
|
myBuf.append(PsiKeyword.NEW).append(" ").append(anonymousClass.getBaseClassType().getPresentableText());
|
||||||
|
if (argumentList != null) argumentList.accept(this);
|
||||||
|
myBuf.append(" {...}");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final PsiJavaCodeReferenceElement reference = expr.getClassReference();
|
||||||
|
if (reference != null) {
|
||||||
|
myBuf.append(PsiKeyword.NEW).append(" ").append(reference.getText());
|
||||||
|
|
||||||
|
final PsiExpression[] arrayDimensions = expr.getArrayDimensions();
|
||||||
|
final PsiType type = expr.getType();
|
||||||
|
final int dimensions = type != null ? type.getArrayDimensions() : arrayDimensions.length;
|
||||||
|
if (arrayDimensions.length > 0) myBuf.append("[");
|
||||||
|
for (int i = 0, arrayDimensionsLength = arrayDimensions.length; i < dimensions; i++) {
|
||||||
|
final PsiExpression dimension = i < arrayDimensionsLength ? arrayDimensions[i] : null;
|
||||||
|
if (i > 0) myBuf.append("][");
|
||||||
|
if (dimension != null) {
|
||||||
|
dimension.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arrayDimensions.length > 0) myBuf.append("]");
|
||||||
|
|
||||||
|
if (argumentList != null) {
|
||||||
|
argumentList.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
final PsiArrayInitializerExpression arrayInitializer = expr.getArrayInitializer();
|
||||||
|
if (arrayInitializer != null) {
|
||||||
|
arrayInitializer.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
myBuf.append(expr.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String render(PsiExpression expression) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
expression.accept(new PsiExpressionTrimRenderer(buf));
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
+360
@@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.psi.util.PsiUtil;
|
||||||
|
import com.intellij.psi.util.TypeConversionUtil;
|
||||||
|
import org.intellij.lang.annotations.MagicConstant;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied from IDEA.
|
||||||
|
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||||
|
* @author Evgeny Gerashchenko
|
||||||
|
* @since 6/26/12
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public class PsiFormatUtil extends PsiFormatUtilBase {
|
||||||
|
@MagicConstant(flags = {SHOW_MODIFIERS, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_MODIFIERS, SHOW_INITIALIZER, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES})
|
||||||
|
public @interface FormatVariableOptions {}
|
||||||
|
|
||||||
|
public static String formatVariable(PsiVariable variable, @FormatVariableOptions int options, PsiSubstitutor substitutor){
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
formatVariable(variable, options, substitutor,buffer);
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
private static void formatVariable(PsiVariable variable,
|
||||||
|
@FormatVariableOptions int options,
|
||||||
|
PsiSubstitutor substitutor,
|
||||||
|
@NotNull StringBuilder buffer){
|
||||||
|
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){
|
||||||
|
formatModifiers(variable, options,buffer);
|
||||||
|
}
|
||||||
|
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
buffer.append(formatType(variable.getType(), options, substitutor));
|
||||||
|
}
|
||||||
|
if (variable instanceof PsiField && (options & SHOW_CONTAINING_CLASS) != 0){
|
||||||
|
PsiClass aClass = ((PsiField)variable).getContainingClass();
|
||||||
|
if (aClass != null){
|
||||||
|
String className = aClass.getName();
|
||||||
|
if (className != null) {
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
if ((options & SHOW_FQ_NAME) != 0){
|
||||||
|
String qName = aClass.getQualifiedName();
|
||||||
|
if (qName != null){
|
||||||
|
buffer.append(qName);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
buffer.append(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
buffer.append(className);
|
||||||
|
}
|
||||||
|
buffer.append('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_NAME) != 0){
|
||||||
|
buffer.append(variable.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if ((options & SHOW_NAME) != 0){
|
||||||
|
String name = variable.getName();
|
||||||
|
if (StringUtil.isNotEmpty(name)){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
buffer.append(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){
|
||||||
|
if ((options & SHOW_NAME) != 0 && variable.getName() != null){
|
||||||
|
buffer.append(':');
|
||||||
|
}
|
||||||
|
buffer.append(formatType(variable.getType(), options, substitutor));
|
||||||
|
}
|
||||||
|
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){
|
||||||
|
formatModifiers(variable, options,buffer);
|
||||||
|
}
|
||||||
|
if ((options & SHOW_INITIALIZER) != 0){
|
||||||
|
PsiExpression initializer = variable.getInitializer();
|
||||||
|
if (initializer != null){
|
||||||
|
buffer.append(" = ");
|
||||||
|
String text = PsiExpressionTrimRenderer.render(initializer);
|
||||||
|
int index1 = text.lastIndexOf('\n');
|
||||||
|
if (index1 < 0) index1 = text.length();
|
||||||
|
int index2 = text.lastIndexOf('\r');
|
||||||
|
if (index2 < 0) index2 = text.length();
|
||||||
|
int index = Math.min(index1, index2);
|
||||||
|
buffer.append(text.substring(0, index));
|
||||||
|
if (index < text.length()) {
|
||||||
|
buffer.append(" ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MagicConstant(flags = {SHOW_MODIFIERS, MODIFIERS_AFTER, SHOW_TYPE, TYPE_AFTER, SHOW_CONTAINING_CLASS, SHOW_FQ_NAME, SHOW_NAME, SHOW_PARAMETERS, SHOW_THROWS, SHOW_RAW_TYPE, SHOW_RAW_NON_TOP_TYPE, SHOW_FQ_CLASS_NAMES})
|
||||||
|
public @interface FormatMethodOptions {}
|
||||||
|
|
||||||
|
private static void formatMethod(PsiMethod method, PsiSubstitutor substitutor, @FormatMethodOptions int options, @FormatVariableOptions int parameterOptions, int maxParametersToShow, StringBuilder buffer){
|
||||||
|
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) == 0){
|
||||||
|
formatModifiers(method, options,buffer);
|
||||||
|
}
|
||||||
|
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) == 0){
|
||||||
|
PsiType type = method.getReturnType();
|
||||||
|
if (type != null){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
buffer.append(formatType(type, options, substitutor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_CONTAINING_CLASS) != 0){
|
||||||
|
PsiClass aClass = method.getContainingClass();
|
||||||
|
if (aClass != null){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
String name = aClass.getName();
|
||||||
|
if (name != null) {
|
||||||
|
if ((options & SHOW_FQ_NAME) != 0){
|
||||||
|
String qName = aClass.getQualifiedName();
|
||||||
|
if (qName != null){
|
||||||
|
buffer.append(qName);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
buffer.append(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
buffer.append(name);
|
||||||
|
}
|
||||||
|
buffer.append('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_NAME) != 0){
|
||||||
|
buffer.append(method.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if ((options & SHOW_NAME) != 0){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
buffer.append(method.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_PARAMETERS) != 0){
|
||||||
|
buffer.append('(');
|
||||||
|
PsiParameter[] parms = method.getParameterList().getParameters();
|
||||||
|
for(int i = 0; i < Math.min(parms.length, maxParametersToShow); i++) {
|
||||||
|
PsiParameter parm = parms[i];
|
||||||
|
if (i > 0){
|
||||||
|
buffer.append(", ");
|
||||||
|
}
|
||||||
|
buffer.append(formatVariable(parm, parameterOptions, substitutor));
|
||||||
|
}
|
||||||
|
if(parms.length > maxParametersToShow) {
|
||||||
|
buffer.append (", ...");
|
||||||
|
}
|
||||||
|
buffer.append(')');
|
||||||
|
}
|
||||||
|
if ((options & SHOW_TYPE) != 0 && (options & TYPE_AFTER) != 0){
|
||||||
|
PsiType type = method.getReturnType();
|
||||||
|
if (type != null){
|
||||||
|
if (buffer.length() > 0){
|
||||||
|
buffer.append(':');
|
||||||
|
}
|
||||||
|
buffer.append(formatType(type, options, substitutor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((options & SHOW_MODIFIERS) != 0 && (options & MODIFIERS_AFTER) != 0){
|
||||||
|
formatModifiers(method, options,buffer);
|
||||||
|
}
|
||||||
|
if ((options & SHOW_THROWS) != 0){
|
||||||
|
String throwsText = formatReferenceList(method.getThrowsList(), options);
|
||||||
|
if (!throwsText.isEmpty()){
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
//noinspection HardCodedStringLiteral
|
||||||
|
buffer.append("throws ");
|
||||||
|
buffer.append(throwsText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void formatModifiers(PsiElement element, int options, StringBuilder buffer) throws IllegalArgumentException{
|
||||||
|
PsiModifierList list;
|
||||||
|
boolean isInterface = false;
|
||||||
|
if (element instanceof PsiVariable){
|
||||||
|
list = ((PsiVariable)element).getModifierList();
|
||||||
|
}
|
||||||
|
else if (element instanceof PsiMethod){
|
||||||
|
list = ((PsiMethod)element).getModifierList();
|
||||||
|
}
|
||||||
|
else if (element instanceof PsiClass){
|
||||||
|
isInterface = ((PsiClass)element).isInterface();
|
||||||
|
list = ((PsiClass)element).getModifierList();
|
||||||
|
if (list == null) return;
|
||||||
|
}
|
||||||
|
else if (element instanceof PsiClassInitializer){
|
||||||
|
list = ((PsiClassInitializer)element).getModifierList();
|
||||||
|
if (list == null) return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
if (list == null) return;
|
||||||
|
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||||
|
? list.hasExplicitModifier(PsiModifier.PUBLIC)
|
||||||
|
: list.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||||
|
appendModifier(buffer, PsiModifier.PUBLIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.hasModifierProperty(PsiModifier.PROTECTED)){
|
||||||
|
appendModifier(buffer, PsiModifier.PROTECTED);
|
||||||
|
}
|
||||||
|
if (list.hasModifierProperty(PsiModifier.PRIVATE)){
|
||||||
|
appendModifier(buffer, PsiModifier.PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||||
|
? list.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)
|
||||||
|
: list.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
|
||||||
|
if (element instanceof PsiClass && element.getParent() instanceof PsiDeclarationStatement) {// local class
|
||||||
|
appendModifier(buffer, "local");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appendModifier(buffer, PsiBundle.visibilityPresentation(PsiModifier.PACKAGE_LOCAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||||
|
? list.hasExplicitModifier(PsiModifier.STATIC)
|
||||||
|
: list.hasModifierProperty(PsiModifier.STATIC)) appendModifier(buffer, PsiModifier.STATIC);
|
||||||
|
|
||||||
|
if (!isInterface && //cls modifier list
|
||||||
|
((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||||
|
? list.hasExplicitModifier(PsiModifier.ABSTRACT)
|
||||||
|
: list.hasModifierProperty(PsiModifier.ABSTRACT))) appendModifier(buffer, PsiModifier.ABSTRACT);
|
||||||
|
|
||||||
|
if ((options & SHOW_REDUNDANT_MODIFIERS) == 0
|
||||||
|
? list.hasExplicitModifier(PsiModifier.FINAL)
|
||||||
|
: list.hasModifierProperty(PsiModifier.FINAL)) appendModifier(buffer, PsiModifier.FINAL);
|
||||||
|
|
||||||
|
if (list.hasModifierProperty(PsiModifier.NATIVE) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||||
|
appendModifier(buffer, PsiModifier.NATIVE);
|
||||||
|
}
|
||||||
|
if (list.hasModifierProperty(PsiModifier.SYNCHRONIZED) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||||
|
appendModifier(buffer, PsiModifier.SYNCHRONIZED);
|
||||||
|
}
|
||||||
|
if (list.hasModifierProperty(PsiModifier.STRICTFP) && (options & JAVADOC_MODIFIERS_ONLY) == 0){
|
||||||
|
appendModifier(buffer, PsiModifier.STRICTFP);
|
||||||
|
}
|
||||||
|
if (list.hasModifierProperty(PsiModifier.TRANSIENT) &&
|
||||||
|
element instanceof PsiVariable // javac 5 puts transient attr for methods
|
||||||
|
){
|
||||||
|
appendModifier(buffer, PsiModifier.TRANSIENT);
|
||||||
|
}
|
||||||
|
if (list.hasModifierProperty(PsiModifier.VOLATILE)){
|
||||||
|
appendModifier(buffer, PsiModifier.VOLATILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendModifier(final StringBuilder buffer, final String modifier) {
|
||||||
|
appendSpaceIfNeeded(buffer);
|
||||||
|
buffer.append(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatReferenceList(PsiReferenceList list, int options){
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
PsiJavaCodeReferenceElement[] refs = list.getReferenceElements();
|
||||||
|
for(int i = 0; i < refs.length; i++) {
|
||||||
|
PsiJavaCodeReferenceElement ref = refs[i];
|
||||||
|
if (i > 0){
|
||||||
|
buffer.append(", ");
|
||||||
|
}
|
||||||
|
buffer.append(formatReference(ref, options));
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatType(PsiType type, int options, @NotNull PsiSubstitutor substitutor){
|
||||||
|
type = substitutor.substitute(type);
|
||||||
|
if ((options & SHOW_RAW_TYPE) != 0) {
|
||||||
|
type = TypeConversionUtil.erasure(type);
|
||||||
|
} else if ((options & SHOW_RAW_NON_TOP_TYPE) != 0) {
|
||||||
|
if (!(PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter)) {
|
||||||
|
final boolean preserveEllipsis = type instanceof PsiEllipsisType;
|
||||||
|
type = TypeConversionUtil.erasure(type);
|
||||||
|
if (preserveEllipsis && type instanceof PsiArrayType) {
|
||||||
|
type = new PsiEllipsisType(((PsiArrayType)type).getComponentType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (options & SHOW_FQ_CLASS_NAMES) == 0 ? type.getPresentableText() : type.getInternalCanonicalText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatReference(PsiJavaCodeReferenceElement ref, int options){
|
||||||
|
return (options & SHOW_FQ_CLASS_NAMES) == 0 ? ref.getText() : ref.getCanonicalText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getExternalName(PsiModifierListOwner owner, final boolean showParamName, int maxParamsToShow) {
|
||||||
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
if (owner instanceof PsiClass) {
|
||||||
|
ClassUtil.formatClassName((PsiClass)owner, builder);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
final PsiClass psiClass = PsiTreeUtil.getParentOfType(owner, PsiClass.class, false);
|
||||||
|
if (psiClass == null) return null;
|
||||||
|
ClassUtil.formatClassName(psiClass, builder);
|
||||||
|
if (owner instanceof PsiMethod) {
|
||||||
|
builder.append(" ");
|
||||||
|
formatMethod((PsiMethod)owner, PsiSubstitutor.EMPTY,
|
||||||
|
SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES,
|
||||||
|
showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder);
|
||||||
|
}
|
||||||
|
else if (owner instanceof PsiField) {
|
||||||
|
builder.append(" ").append(((PsiField)owner).getName());
|
||||||
|
}
|
||||||
|
else if (owner instanceof PsiParameter) {
|
||||||
|
final PsiElement declarationScope = ((PsiParameter)owner).getDeclarationScope();
|
||||||
|
if (!(declarationScope instanceof PsiMethod)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final PsiMethod psiMethod = (PsiMethod)declarationScope;
|
||||||
|
|
||||||
|
builder.append(" ");
|
||||||
|
formatMethod(psiMethod, PsiSubstitutor.EMPTY,
|
||||||
|
SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES,
|
||||||
|
showParamName ? SHOW_NAME | SHOW_TYPE | SHOW_FQ_CLASS_NAMES : SHOW_TYPE | SHOW_FQ_CLASS_NAMES, maxParamsToShow, builder);
|
||||||
|
builder.append(" ");
|
||||||
|
|
||||||
|
if (showParamName) {
|
||||||
|
formatVariable((PsiVariable)owner, SHOW_NAME, PsiSubstitutor.EMPTY, builder);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.append(psiMethod.getParameterList().getParameterIndex((PsiParameter)owner));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.lang.resolve.java.extAnnotations;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied from IDEA.
|
||||||
|
* This class should be eliminated when Kotlin will depend on IDEA 12.x (KT-2326)
|
||||||
|
* @author Evgeny Gerashchenko
|
||||||
|
* @since 6/26/12
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public abstract class PsiFormatUtilBase {
|
||||||
|
|
||||||
|
public static final int SHOW_NAME = 0x0001; // variable, method, class
|
||||||
|
public static final int SHOW_TYPE = 0x0002; // variable, method
|
||||||
|
public static final int TYPE_AFTER = 0x0004; // variable, method
|
||||||
|
public static final int SHOW_MODIFIERS = 0x0008; // variable, method, class
|
||||||
|
public static final int MODIFIERS_AFTER = 0x0010; // variable, method, class
|
||||||
|
public static final int SHOW_REDUNDANT_MODIFIERS = 0x0020; // variable, method, class, modifier list
|
||||||
|
public static final int SHOW_PACKAGE_LOCAL = 0x0040; // variable, method, class, modifier list
|
||||||
|
public static final int SHOW_INITIALIZER = 0x0080; // variable
|
||||||
|
public static final int SHOW_PARAMETERS = 0x0100; // method
|
||||||
|
public static final int SHOW_THROWS = 0x0200; // method
|
||||||
|
public static final int SHOW_EXTENDS_IMPLEMENTS = 0x0400; // class
|
||||||
|
public static final int SHOW_FQ_NAME = 0x0800; // class, field, method
|
||||||
|
public static final int SHOW_CONTAINING_CLASS = 0x1000; // field, method
|
||||||
|
public static final int SHOW_FQ_CLASS_NAMES = 0x2000; // variable, method, class
|
||||||
|
public static final int JAVADOC_MODIFIERS_ONLY = 0x4000; // field, method, class
|
||||||
|
public static final int SHOW_ANONYMOUS_CLASS_VERBOSE = 0x8000; // class
|
||||||
|
public static final int SHOW_RAW_TYPE = 0x10000; //type
|
||||||
|
public static final int SHOW_RAW_NON_TOP_TYPE = 0x20000;
|
||||||
|
public static final int MAX_PARAMS_TO_SHOW = 7;
|
||||||
|
|
||||||
|
protected static void appendSpaceIfNeeded(StringBuilder buffer) {
|
||||||
|
if (buffer.length() != 0 && !StringUtil.endsWithChar(buffer, ' ')) {
|
||||||
|
buffer.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user