Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir Orlov
2014-03-04 16:45:06 +04:00
74 changed files with 1129 additions and 540 deletions
@@ -21,34 +21,37 @@
package com.intellij.debugger.actions;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.debugger.ui.ValueHint;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class QuickEvaluateActionHandler extends QuickEvaluateHandler {
@Override
public boolean isEnabled(@NotNull final Project project) {
DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
return debuggerSession != null && debuggerSession.isPaused();
}
@Override
public AbstractValueHint createValueHint(@NotNull final Project project, @NotNull final Editor editor, @NotNull final Point point, final ValueHintType type) {
return ValueHint.createValueHint(project, editor, point, type);
}
@Override
public boolean canShowHint(@NotNull final Project project) {
DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
return debuggerSession != null && debuggerSession.isAttached();
}
@Override
public int getValueLookupDelay(final Project project) {
return DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY;
}
@@ -71,61 +71,73 @@ public class JavaDebuggerSupport extends DebuggerSupport {
private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
@Override
@NotNull
public BreakpointPanelProvider<?> getBreakpointPanelProvider() {
return myBreakpointPanelProvider;
}
@Override
@NotNull
public DebuggerActionHandler getStepOverHandler() {
return myStepOverActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getStepIntoHandler() {
return myStepIntoActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getSmartStepIntoHandler() {
return mySmartStepIntoHandler;
}
@Override
@NotNull
public DebuggerActionHandler getStepOutHandler() {
return myStepOutActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getForceStepOverHandler() {
return myForceStepOverActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getForceStepIntoHandler() {
return myForceStepIntoActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getRunToCursorHandler() {
return myRunToCursorActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getForceRunToCursorHandler() {
return myForceRunToCursorActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getResumeActionHandler() {
return myResumeActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getPauseHandler() {
return myPauseActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getToggleLineBreakpointHandler() {
return DISABLED;
@@ -137,16 +149,19 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return DISABLED;
}
@Override
@NotNull
public DebuggerActionHandler getShowExecutionPointHandler() {
return myShowExecutionPointActionHandler;
}
@Override
@NotNull
public DebuggerActionHandler getEvaluateHandler() {
return myEvaluateActionHandler;
}
@Override
@NotNull
public QuickEvaluateHandler getQuickEvaluateHandler() {
return myQuickEvaluateHandler;
@@ -158,6 +173,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return myAddToWatchedActionHandler;
}
@Override
@NotNull
public DebuggerToggleActionHandler getMuteBreakpointsHandler() {
return myMuteBreakpointsHandler;
@@ -181,6 +197,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return DISABLED_EDIT;
}
@Override
@NotNull
public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
return myDebuggerSettingsPanelProvider;
@@ -233,10 +250,12 @@ public class JavaDebuggerSupport extends DebuggerSupport {
//}
}
@Override
public int getPriority() {
return 100;
}
@Override
public Breakpoint findBreakpoint(@NotNull final Project project, @NotNull final Document document, final int offset) {
return null;
//return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().findBreakpoint(document, offset, null);
@@ -253,6 +272,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return null;
}
@Override
public void onDialogClosed(final Project project) {
//DebuggerManagerEx.getInstanceEx(project).getBreakpointManager().updateAllRequests();
}
@@ -308,6 +328,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
}
public static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider {
@Override
public int getPriority() {
return 1;
}
@@ -317,6 +338,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return new DebuggerLaunchingConfigurable();
}
@Override
public Collection<? extends Configurable> getConfigurables() {
final ArrayList<Configurable> configurables = new ArrayList<Configurable>();
configurables.add(new DebuggerDataViewsConfigurable(null));
@@ -326,6 +348,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
return configurables;
}
@Override
public void apply() {
NodeRendererSettings.getInstance().fireRenderersChanged();
}
@@ -42,13 +42,12 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.jsp.JspFile;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
@@ -296,8 +295,8 @@ public abstract class BreakpointWithHighlighter<P extends JavaBreakpointProperti
ApplicationManager.getApplication().assertReadAccessAllowed();
final XSourcePosition position = myXBreakpoint.getSourcePosition();
try {
PsiElement element = XDebuggerUtil.getInstance().findContextElement(position.getFile(), position.getOffset(), myProject, false);
mySourcePosition = SourcePosition.createFromOffset(element.getContainingFile(), position.getOffset());
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(position.getFile());
mySourcePosition = SourcePosition.createFromOffset(psiFile, position.getOffset());
} catch (Exception e) {
mySourcePosition = null;
}
@@ -15,7 +15,12 @@
*/
package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.ui.JavaDebuggerSupport;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointType;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
@@ -53,4 +58,18 @@ public abstract class JavaBreakpointTypeBase<T extends JavaBreakpointProperties>
public final XDebuggerEditorsProvider getEditorsProvider(@NotNull XBreakpoint<T> breakpoint, @NotNull Project project) {
return new JavaDebuggerEditorsProvider();
}
@Nullable
@Override
public XSourcePosition getSourcePosition(@NotNull XBreakpoint<T> breakpoint) {
BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(JavaDebuggerSupport.getCurrentProject()).getBreakpointManager();
Breakpoint javaBreakpoint = breakpointManager.findBreakpoint(breakpoint);
if (javaBreakpoint != null) {
PsiClass aClass = javaBreakpoint.getPsiClass();
if (aClass != null && aClass.getContainingFile() != null) {
return XDebuggerUtil.getInstance().createPositionByOffset(aClass.getContainingFile().getVirtualFile(), aClass.getTextOffset());
}
}
return null;
}
}
@@ -23,13 +23,17 @@ import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.sun.jdi.AbsentInformationException;
@@ -83,7 +87,11 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro
}
public PsiClass getPsiClass() {
return null;
return PsiDocumentManager.getInstance(myProject).commitAndRunReadAction(new Computable<PsiClass>() {
public PsiClass compute() {
return getClassName() != null ? DebuggerUtilsEx.findClass(getClassName(), myProject, GlobalSearchScope.allScope(myProject)) : null;
}
});
}
public String getDisplayName() {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -33,10 +33,11 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.util.ObjectUtils.assertNotNull;
public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final PsiType myType;
@@ -75,28 +76,26 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement
addTypeCast(project, (PsiExpression)startElement, myType);
}
private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) throws IncorrectOperationException {
private static void addTypeCast(Project project, PsiExpression originalExpression, PsiType type) {
PsiExpression typeCast = createCastExpression(originalExpression, project, type);
originalExpression.replace(typeCast);
}
static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) throws IncorrectOperationException {
static PsiExpression createCastExpression(PsiExpression originalExpression, Project project, PsiType type) {
// remove nested casts
PsiElement element = PsiUtil.deparenthesizeExpression(originalExpression);
if (element == null){
return null;
}
PsiElement expression = PsiUtil.deparenthesizeExpression(originalExpression);
if (expression == null) return null;
PsiElementFactory factory = JavaPsiFacade.getInstance(originalExpression.getProject()).getElementFactory();
PsiTypeCastExpression typeCast = (PsiTypeCastExpression)factory.createExpressionFromText("(Type)value", null);
assertNotNull(typeCast.getCastType()).replace(factory.createTypeElement(type));
typeCast = (PsiTypeCastExpression)CodeStyleManager.getInstance(project).reformat(typeCast);
typeCast.getCastType().replace(factory.createTypeElement(type));
if (element instanceof PsiConditionalExpression) {
// we'd better cast one branch of ternary expression if we could
PsiConditionalExpression expression = (PsiConditionalExpression)element.copy();
PsiExpression thenE = expression.getThenExpression();
PsiExpression elseE = expression.getElseExpression();
if (expression instanceof PsiConditionalExpression) {
// we'd better cast one branch of ternary expression if we can
PsiConditionalExpression conditional = (PsiConditionalExpression)expression.copy();
PsiExpression thenE = conditional.getThenExpression();
PsiExpression elseE = conditional.getElseExpression();
PsiType thenType = thenE == null ? null : thenE.getType();
PsiType elseType = elseE == null ? null : elseE.getType();
if (elseType != null && thenType != null) {
@@ -104,18 +103,20 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement
boolean replaceElse = !TypeConversionUtil.isAssignable(type, elseType);
if (replaceThen != replaceElse) {
if (replaceThen) {
typeCast.getOperand().replace(thenE);
assertNotNull(typeCast.getOperand()).replace(thenE);
thenE.replace(typeCast);
}
else {
typeCast.getOperand().replace(elseE);
assertNotNull(typeCast.getOperand()).replace(elseE);
elseE.replace(typeCast);
}
return expression;
return conditional;
}
}
}
typeCast.getOperand().replace(element);
assertNotNull(typeCast.getOperand()).replace(expression);
return typeCast;
}
@@ -60,6 +60,12 @@ public class JavaReferenceAdjuster implements ReferenceAdjuster {
}
if (rightKind) {
// annotations may jump out of reference (see PsiJavaCodeReferenceImpl#setAnnotations()) so they should be processed first
List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(ref, PsiAnnotation.class);
for (PsiAnnotation annotation : annotations) {
process(annotation.getNode(), addImports, incompleteCode, useFqInJavadoc, useFqInCode);
}
boolean isInsideDocComment = TreeUtil.findParent(element, JavaDocElementType.DOC_COMMENT) != null;
boolean isShort = !ref.isQualified();
if (isInsideDocComment ? !useFqInJavadoc : !useFqInCode) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* 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.
@@ -18,6 +18,7 @@ package com.intellij.refactoring.typeMigration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.impl.PsiDiamondTypeUtil;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositeElement;
@@ -109,18 +110,19 @@ public class TypeMigrationReplacementUtil {
if (!migratedType.isValid()) {
migratedType = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(migratedType.getCanonicalText());
}
final PsiTypeElement typeElement =
JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType);
final PsiTypeElement typeElement = JavaPsiFacade.getInstance(project).getElementFactory().createTypeElement(migratedType);
if (element instanceof PsiMethod) {
final PsiTypeElement returnTypeElement = ((PsiMethod)element).getReturnTypeElement();
if (returnTypeElement != null) {
returnTypeElement.replace(typeElement);
final PsiElement replaced = returnTypeElement.replace(typeElement);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
}
}
else if (element instanceof PsiVariable) {
final PsiTypeElement varTypeElement = ((PsiVariable)element).getTypeElement();
if (varTypeElement != null) {
varTypeElement.replace(typeElement);
final PsiElement replaced = varTypeElement.replace(typeElement);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
}
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -16,7 +16,6 @@
package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -24,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
*
* @author max
*/
public class PsiArrayType extends PsiType {
public class PsiArrayType extends PsiType.Stub {
private final PsiType myComponentType;
/**
@@ -44,19 +43,33 @@ public class PsiArrayType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
return StringUtil.join(myComponentType.getPresentableText(), getAnnotationsTextPrefix(false, true, true), "[]");
return getText(myComponentType.getPresentableText(), "[]", false, true);
}
@NotNull
@Override
public String getCanonicalText() {
return StringUtil.join(myComponentType.getCanonicalText(), "[]");
public String getCanonicalText(boolean annotated) {
return getText(myComponentType.getCanonicalText(annotated), "[]", true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
return StringUtil.join(myComponentType.getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "[]");
return getText(myComponentType.getInternalCanonicalText(), "[]", true, true);
}
protected String getText(@NotNull String prefix, @NotNull String suffix, boolean qualified, boolean annotated) {
StringBuilder sb = new StringBuilder(prefix.length() + suffix.length());
sb.append(prefix);
if (annotated) {
PsiAnnotation[] annotations = getAnnotations();
if (annotations.length != 0) {
sb.append(' ');
PsiNameHelper.appendAnnotations(sb, annotations, qualified);
}
}
sb.append(suffix);
return sb.toString();
}
@Override
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author ven
*/
public class PsiCapturedWildcardType extends PsiType {
public class PsiCapturedWildcardType extends PsiType.Stub {
@NotNull private final PsiWildcardType myExistential;
@NotNull private final PsiElement myContext;
@Nullable private final PsiTypeParameter myParameter;
@@ -78,8 +78,8 @@ public class PsiCapturedWildcardType extends PsiType {
@NotNull
@Override
public String getCanonicalText() {
return myExistential.getCanonicalText();
public String getCanonicalText(boolean annotated) {
return myExistential.getCanonicalText(annotated);
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -280,4 +280,23 @@ public abstract class PsiClassType extends PsiType {
}
};
}
/**
* Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}.
*/
public static abstract class Stub extends PsiClassType {
protected Stub(LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) {
super(languageLevel, annotations);
}
@NotNull
@Override
public final String getCanonicalText() {
return getCanonicalText(false);
}
@NotNull
@Override
public abstract String getCanonicalText(boolean annotated);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -33,7 +33,7 @@ import java.util.List;
* Composite type resulting from Project Coin's multi-catch statements, i.e. <code>FileNotFoundException | EOFException</code>.
* In most cases should be threatened via its least upper bound (<code>IOException</code> in the example above).
*/
public class PsiDisjunctionType extends PsiType {
public class PsiDisjunctionType extends PsiType.Stub {
private final PsiManager myManager;
private final List<PsiType> myTypes;
private final CachedValue<PsiType> myLubCache;
@@ -85,15 +85,21 @@ public class PsiDisjunctionType extends PsiType {
@Override
public String getPresentableText() {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
@Override public String fun(PsiType psiType) { return psiType.getPresentableText(); }
@Override
public String fun(PsiType psiType) {
return psiType.getPresentableText();
}
}, " | ");
}
@NotNull
@Override
public String getCanonicalText() {
public String getCanonicalText(final boolean annotated) {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
@Override public String fun(PsiType psiType) { return psiType.getCanonicalText(); }
@Override
public String fun(PsiType psiType) {
return psiType.getCanonicalText(annotated);
}
}, " | ");
}
@@ -101,7 +107,10 @@ public class PsiDisjunctionType extends PsiType {
@Override
public String getInternalCanonicalText() {
return StringUtil.join(myTypes, new Function<PsiType, String>() {
@Override public String fun(PsiType psiType) { return psiType.getInternalCanonicalText(); }
@Override
public String fun(PsiType psiType) {
return psiType.getInternalCanonicalText();
}
}, " | ");
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -15,7 +15,6 @@
*/
package com.intellij.psi;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -45,19 +44,19 @@ public class PsiEllipsisType extends PsiArrayType {
@NotNull
@Override
public String getPresentableText() {
return StringUtil.join(getComponentType().getPresentableText(), getAnnotationsTextPrefix(false, true, true), "...");
return getText(getComponentType().getPresentableText(), "...", false, true);
}
@NotNull
@Override
public String getCanonicalText() {
return StringUtil.join(getComponentType().getCanonicalText(), "...");
public String getCanonicalText(boolean annotated) {
return getText(getComponentType().getCanonicalText(annotated), "...", true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
return StringUtil.join(getComponentType().getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "...");
return getText(getComponentType().getInternalCanonicalText(), "...", true, true);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -29,7 +29,7 @@ import java.util.*;
*
* @author ven
*/
public class PsiIntersectionType extends PsiType {
public class PsiIntersectionType extends PsiType.Stub {
private final PsiType[] myConjuncts;
private PsiIntersectionType(@NotNull PsiType[] conjuncts) {
@@ -111,19 +111,19 @@ public class PsiIntersectionType extends PsiType {
@NotNull
@Override
public String getCanonicalText() {
return myConjuncts[0].getCanonicalText();
public String getCanonicalText(boolean annotated) {
return myConjuncts[0].getCanonicalText(annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < myConjuncts.length; i++) {
buffer.append(myConjuncts[i].getInternalCanonicalText());
if (i < myConjuncts.length - 1) buffer.append(" & ");
}
return buffer.toString();
return StringUtil.join(myConjuncts, new Function<PsiType, String>() {
@Override
public String fun(PsiType psiType) {
return psiType.getInternalCanonicalText();
}
}, " & ");
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -23,8 +23,11 @@ import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import static com.intellij.util.ObjectUtils.assertNotNull;
import static com.intellij.util.ObjectUtils.notNull;
/**
@@ -37,7 +40,7 @@ public abstract class PsiNameHelper {
public static PsiNameHelper getInstance(Project project) {
return ServiceManager.getService(project, PsiNameHelper.class);
}
/**
* Checks if the specified text is a Java identifier, using the language level of the project
* with which the name helper is associated to filter out keywords.
@@ -121,30 +124,15 @@ public abstract class PsiNameHelper {
}
@NotNull
public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] typeParameters) {
if (typeParameters.length == 0 && annotations.length == 0) {
public static String getPresentableText(@Nullable String refName, @NotNull PsiAnnotation[] annotations, @NotNull PsiType[] types) {
if (types.length == 0 && annotations.length == 0) {
return refName != null ? refName : "";
}
StringBuilder buffer = new StringBuilder();
if (annotations.length > 0) {
for (PsiAnnotation annotation : annotations) {
buffer.append(annotation.getText()).append(' ');
}
}
appendAnnotations(buffer, annotations, false);
buffer.append(refName);
if (typeParameters.length > 0) {
buffer.append("<");
for (int i = 0; i < typeParameters.length; i++) {
buffer.append(typeParameters[i].getPresentableText());
if (i < typeParameters.length - 1) buffer.append(", ");
}
buffer.append(">");
}
appendTypeArgs(buffer, types, false, true);
return buffer.toString();
}
@@ -262,4 +250,43 @@ public abstract class PsiNameHelper {
return subpackageName.equals(packageName) ||
subpackageName.startsWith(packageName) && subpackageName.charAt(packageName.length()) == '.';
}
public static void appendTypeArgs(@NotNull StringBuilder sb, @NotNull PsiType[] types, boolean canonical, boolean annotated) {
if (types.length == 0) return;
sb.append('<');
for (int i = 0; i < types.length; i++) {
if (i > 0) {
sb.append(canonical ? "," : ", ");
}
PsiType type = types[i];
if (canonical) {
sb.append(type.getCanonicalText(annotated));
}
else {
sb.append(type.getPresentableText());
}
}
sb.append('>');
}
public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull PsiAnnotation[] annotations, boolean canonical) {
return appendAnnotations(sb, Arrays.asList(annotations), canonical);
}
public static boolean appendAnnotations(@NotNull StringBuilder sb, @NotNull List<PsiAnnotation> annotations, boolean canonical) {
for (PsiAnnotation annotation : annotations) {
sb.append('@');
if (canonical) {
sb.append(annotation.getQualifiedName());
sb.append(annotation.getParameterList().getText());
}
else {
sb.append(assertNotNull(annotation.getNameReferenceElement()).getText());
}
sb.append(' ');
}
return annotations.size() > 0;
}
}
@@ -30,7 +30,7 @@ import java.util.Map;
/**
* Represents primitive types of Java language.
*/
public class PsiPrimitiveType extends PsiType {
public class PsiPrimitiveType extends PsiType.Stub {
private static final Map<String, PsiPrimitiveType> ourQNameToUnboxed = new THashMap<String, PsiPrimitiveType>();
private static final Map<PsiPrimitiveType, String> ourUnboxedToQName = new THashMap<PsiPrimitiveType, String>();
@@ -52,19 +52,29 @@ public class PsiPrimitiveType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
return getAnnotationsTextPrefix(false, false, true) + myName;
return getText(false, true);
}
@NotNull
@Override
public String getCanonicalText() {
return myName;
public String getCanonicalText(boolean annotated) {
return getText(true, annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
return getAnnotationsTextPrefix(true, false, true) + myName;
return getText(true, true);
}
private String getText(boolean qualified, boolean annotated) {
PsiAnnotation[] annotations = getAnnotations();
if (!annotated || annotations.length == 0) return myName;
StringBuilder sb = new StringBuilder();
PsiNameHelper.appendAnnotations(sb, annotations, qualified);
sb.append(myName);
return sb.toString();
}
/**
@@ -84,6 +84,15 @@ public abstract class PsiType implements PsiAnnotationOwner {
*/
@NonNls
@NotNull
public String getCanonicalText(boolean annotated) {
return getCanonicalText();
}
/**
* Same as {@code getCanonicalText(false)}.
*/
@NonNls
@NotNull
public abstract String getCanonicalText();
/**
@@ -284,24 +293,15 @@ public abstract class PsiType implements PsiAnnotationOwner {
return getAnnotations();
}
@NotNull
/** @deprecated use {@link PsiNameHelper#appendAnnotations(StringBuilder, PsiAnnotation[], boolean)} (to remove in IDEA 14) */
@SuppressWarnings("UnusedDeclaration")
protected String getAnnotationsTextPrefix(boolean qualified, boolean leadingSpace, boolean trailingSpace) {
PsiAnnotation[] annotations = getAnnotations();
if (annotations.length == 0) return "";
StringBuilder sb = new StringBuilder();
if (leadingSpace) sb.append(' ');
for (int i = 0; i < annotations.length; i++) {
if (i > 0) sb.append(' ');
PsiAnnotation annotation = annotations[i];
if (qualified) {
sb.append('@').append(annotation.getQualifiedName()).append(annotation.getParameterList().getText());
}
else {
sb.append(annotation.getText());
}
}
if (trailingSpace) sb.append(' ');
if (PsiNameHelper.appendAnnotations(sb, annotations, qualified) &&!trailingSpace) sb.setLength(sb.length() - 1);
return sb.toString();
}
@@ -310,4 +310,23 @@ public abstract class PsiType implements PsiAnnotationOwner {
//noinspection HardCodedStringLiteral
return "PsiType:" + getPresentableText();
}
/**
* Temporary class to facilitate transition to {@link #getCanonicalText(boolean)}.
*/
protected static abstract class Stub extends PsiType {
protected Stub(@NotNull PsiAnnotation[] annotations) {
super(annotations);
}
@NotNull
@Override
public final String getCanonicalText() {
return getCanonicalText(false);
}
@NotNull
@Override
public abstract String getCanonicalText(boolean annotated);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
*
* @author dsl
*/
public class PsiWildcardType extends PsiType {
public class PsiWildcardType extends PsiType.Stub {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.PsiWildcardType");
private static final Key<PsiWildcardType> UNBOUNDED_WILDCARD = new Key<PsiWildcardType>("UNBOUNDED_WILDCARD");
@@ -83,21 +83,37 @@ public class PsiWildcardType extends PsiType {
@NotNull
@Override
public String getPresentableText() {
return getAnnotationsTextPrefix(false, false, true) +
(myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getPresentableText());
return getText(false, true, myBound == null ? null : myBound.getPresentableText());
}
@Override
@NotNull
public String getCanonicalText() {
return myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getCanonicalText();
public String getCanonicalText(boolean annotated) {
return getText(true, annotated, myBound == null ? null : myBound.getCanonicalText(annotated));
}
@NotNull
@Override
public String getInternalCanonicalText() {
return getAnnotationsTextPrefix(true, false, true) +
(myBound == null ? "?" : (myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX) + myBound.getInternalCanonicalText());
return getText(true, true, myBound == null ? null : myBound.getInternalCanonicalText());
}
private String getText(boolean qualified, boolean annotated, @Nullable String suffix) {
PsiAnnotation[] annotations = getAnnotations();
if ((!annotated || annotations.length == 0) && suffix == null) return "?";
StringBuilder sb = new StringBuilder();
if (annotated) {
PsiNameHelper.appendAnnotations(sb, annotations, qualified);
}
if (suffix == null) {
sb.append('?');
}
else {
sb.append(myIsExtending ? EXTENDS_PREFIX : SUPER_PREFIX);
sb.append(suffix);
}
return sb.toString();
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -30,16 +30,16 @@ import java.util.List;
/**
* @author max
*/
public class PsiClassReferenceType extends PsiClassType {
public class PsiClassReferenceType extends PsiClassType.Stub {
@NotNull
private final PsiJavaCodeReferenceElement myReference;
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel) {
this(reference, langLevel, collectAnnotations(reference));
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level) {
this(reference, level, collectAnnotations(reference));
}
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel, @NotNull PsiAnnotation[] annotations) {
super(langLevel, annotations);
public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel level, @NotNull PsiAnnotation[] annotations) {
super(level, annotations);
myReference = reference;
}
@@ -89,7 +89,7 @@ public class PsiClassReferenceType extends PsiClassType {
return resolveGenerics().getElement();
}
private static class DelegatingClassResolveResult implements ClassResolveResult {
private static class DelegatingClassResolveResult implements PsiClassType.ClassResolveResult {
private final JavaResolveResult myDelegate;
private DelegatingClassResolveResult(@NotNull JavaResolveResult delegate) {
@@ -182,19 +182,37 @@ public class PsiClassReferenceType extends PsiClassType {
@NotNull
@Override
public String getPresentableText() {
return getAnnotationsTextPrefix(false, false, true) + PsiNameHelper.getPresentableText(myReference);
String presentableText = PsiNameHelper.getPresentableText(myReference);
PsiAnnotation[] annotations = getAnnotations();
if (annotations.length == 0) return presentableText;
StringBuilder sb = new StringBuilder();
PsiNameHelper.appendAnnotations(sb, annotations, false);
sb.append(presentableText);
return sb.toString();
}
@NotNull
@Override
public String getCanonicalText() {
return myReference.getCanonicalText();
public String getCanonicalText(boolean annotated) {
return getText(annotated);
}
@NotNull
@Override
public String getInternalCanonicalText() {
return getAnnotationsTextPrefix(true, false, true) + getCanonicalText();
return getText(true);
}
private String getText(boolean annotated) {
if (myReference instanceof PsiJavaCodeReferenceElementImpl) {
PsiAnnotation[] annotations = getAnnotations();
if (!annotated || annotations.length == 0) annotations = null;
return ((PsiJavaCodeReferenceElementImpl)myReference).getCanonicalText(annotated, annotations);
}
else {
return myReference.getCanonicalText();
}
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -30,11 +31,12 @@ import java.util.List;
/**
* @author dsl
*/
public class PsiImmediateClassType extends PsiClassType {
public class PsiImmediateClassType extends PsiClassType.Stub {
private final PsiClass myClass;
private final PsiSubstitutor mySubstitutor;
private final PsiManager myManager;
private String myCanonicalText;
private String myCanonicalTextAnnotated;
private String myPresentableText;
private String myInternalCanonicalText;
@@ -80,15 +82,15 @@ public class PsiImmediateClassType extends PsiClassType {
this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY);
}
public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) {
this(aClass, substitutor, languageLevel, PsiAnnotation.EMPTY_ARRAY);
public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel level) {
this(aClass, substitutor, level, PsiAnnotation.EMPTY_ARRAY);
}
public PsiImmediateClassType(@NotNull PsiClass aClass,
@NotNull PsiSubstitutor substitutor,
@Nullable LanguageLevel languageLevel,
@NotNull PsiAnnotation[] annotations) {
super(languageLevel, annotations);
@Nullable LanguageLevel level,
@NotNull PsiAnnotation... annotations) {
super(level, annotations);
myClass = aClass;
myManager = aClass.getManager();
mySubstitutor = substitutor;
@@ -138,112 +140,119 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
public String getPresentableText() {
if (myPresentableText == null) {
StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, false, false);
myPresentableText = buffer.toString();
myPresentableText = getText(TextType.PRESENTABLE, true);
}
return myPresentableText;
}
@NotNull
@Override
public String getCanonicalText() {
if (myCanonicalText == null) {
assert mySubstitutor.isValid();
StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, true, false);
myCanonicalText = buffer.toString();
public String getCanonicalText(boolean annotated) {
String cached = annotated ? myCanonicalTextAnnotated : myCanonicalText;
if (cached == null) {
cached = getText(TextType.CANONICAL, annotated);
if (annotated) myCanonicalTextAnnotated = cached;
else myCanonicalText = cached;
}
return myCanonicalText;
return cached;
}
@NotNull
@Override
public String getInternalCanonicalText() {
if (myInternalCanonicalText == null) {
StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, true, true);
myInternalCanonicalText = buffer.toString();
myInternalCanonicalText = getText(TextType.INT_CANONICAL, true);
}
return myInternalCanonicalText;
}
private enum TextType { PRESENTABLE, CANONICAL, INT_CANONICAL }
private String getText(@NotNull TextType textType, boolean annotated) {
assert mySubstitutor.isValid();
StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, textType, annotated);
return buffer.toString();
}
private void buildText(@NotNull PsiClass aClass,
@NotNull PsiSubstitutor substitutor,
@NotNull StringBuilder buffer,
boolean canonical,
boolean internal) {
@NotNull TextType textType,
boolean annotated) {
if (aClass instanceof PsiAnonymousClass) {
ClassResolveResult baseResolveResult = ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics();
ClassResolveResult baseResolveResult = ((PsiAnonymousClass)aClass).getBaseClassType().resolveGenerics();
PsiClass baseClass = baseResolveResult.getElement();
PsiSubstitutor baseSub = baseResolveResult.getSubstitutor();
if (baseClass != null) {
buildText(baseClass, baseSub, buffer, canonical, internal);
buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false);
}
return;
}
if (canonical == internal) {
buffer.append(getAnnotationsTextPrefix(internal, false, true));
}
boolean qualified = textType != TextType.PRESENTABLE;
PsiClass enclosingClass = null;
if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
final PsiElement parent = aClass.getParent();
PsiElement parent = aClass.getParent();
if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) {
enclosingClass = (PsiClass)parent;
}
}
if (enclosingClass != null) {
buildText(enclosingClass, substitutor, buffer, canonical, false);
buildText(enclosingClass, substitutor, buffer, textType, false);
buffer.append('.');
buffer.append(aClass.getName());
}
else {
final String name;
if (!canonical) {
name = aClass.getName();
}
else {
final String qualifiedName = aClass.getQualifiedName();
if (qualifiedName == null) {
name = aClass.getName();
}
else {
name = qualifiedName;
else if (qualified) {
String fqn = aClass.getQualifiedName();
if (fqn != null) {
String prefix = StringUtil.getPackageName(fqn);
if (!StringUtil.isEmpty(prefix)) {
buffer.append(prefix);
buffer.append('.');
}
}
buffer.append(name);
}
if (annotated) {
PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified);
}
buffer.append(aClass.getName());
PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
if (typeParameters.length > 0) {
StringBuilder pineBuffer = new StringBuilder();
pineBuffer.append('<');
int pos = buffer.length();
buffer.append('<');
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter typeParameter = typeParameters[i];
PsiUtilCore.ensureValid(typeParameter);
if (i > 0) pineBuffer.append(',');
final PsiType substitutionResult = substitutor.substitute(typeParameter);
if (i > 0) {
buffer.append(',');
if (textType == TextType.PRESENTABLE) buffer.append(' ');
}
PsiType substitutionResult = substitutor.substitute(typeParameter);
if (substitutionResult == null) {
pineBuffer = null;
buffer.setLength(pos);
pos = -1;
break;
}
PsiUtil.ensureValidType(substitutionResult);
if (canonical) {
if (internal) {
pineBuffer.append(substitutionResult.getInternalCanonicalText());
}
else {
pineBuffer.append(substitutionResult.getCanonicalText());
}
if (textType == TextType.PRESENTABLE) {
buffer.append(substitutionResult.getPresentableText());
}
else if (textType == TextType.CANONICAL) {
buffer.append(substitutionResult.getCanonicalText(annotated));
}
else {
pineBuffer.append(substitutionResult.getPresentableText());
buffer.append(substitutionResult.getInternalCanonicalText());
}
}
if (pineBuffer != null) {
buffer.append(pineBuffer);
if (pos >= 0) {
buffer.append('>');
}
}
@@ -265,7 +274,6 @@ public class PsiImmediateClassType extends PsiClassType {
return false;
}
return equals(patternType);
}
@Override
@@ -277,14 +285,12 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
@NotNull
public LanguageLevel getLanguageLevel() {
if (myLanguageLevel != null) return myLanguageLevel;
return PsiUtil.getLanguageLevel(myClass);
return myLanguageLevel != null ? myLanguageLevel : PsiUtil.getLanguageLevel(myClass);
}
@NotNull
@Override
public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) {
if (languageLevel.equals(myLanguageLevel)) return this;
return new PsiImmediateClassType(myClass, mySubstitutor, languageLevel,getAnnotations());
public PsiClassType setLanguageLevel(@NotNull LanguageLevel level) {
return level.equals(myLanguageLevel) ? this : new PsiImmediateClassType(myClass, mySubstitutor, level, getAnnotations());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -49,6 +49,7 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiJavaCodeReferenceElement, SourceJavaCodeReference {
@@ -255,36 +256,47 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
@Override
@NotNull
public String getCanonicalText() {
return getCanonicalText(false, null);
}
@NotNull
public String getCanonicalText(boolean annotated, @Nullable PsiAnnotation[] annotations) {
switch (getKind()) {
case CLASS_NAME_KIND:
case CLASS_OR_PACKAGE_NAME_KIND:
case CLASS_IN_QUALIFIED_NEW_KIND:
final PsiElement target = resolve();
if (target instanceof PsiClass) {
final PsiClass aClass = (PsiClass)target;
String name = aClass.getQualifiedName();
if (name == null) {
name = aClass.getName(); //?
PsiClass aClass = (PsiClass)target;
StringBuilder buffer = new StringBuilder();
PsiElement qualifier = getQualifier();
String prefix = null;
if (qualifier instanceof PsiJavaCodeReferenceElementImpl) {
prefix = ((PsiJavaCodeReferenceElementImpl)qualifier).getCanonicalText(annotated, null);
}
final PsiType[] types = getTypeParameters();
if (types.length == 0) {
final PsiElement qualifier = getQualifier();
if (qualifier instanceof PsiJavaCodeReferenceElement) {
return StringUtil.getQualifiedName(((PsiJavaCodeReferenceElement)qualifier).getCanonicalText(), aClass.getName());
else {
String fqn = aClass.getQualifiedName();
if (fqn != null) {
prefix = StringUtil.getPackageName(fqn);
}
return name;
}
final 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());
if (!StringUtil.isEmpty(prefix)) {
buffer.append(prefix);
buffer.append('.');
}
buf.append('>');
return buf.toString();
if (annotated) {
List<PsiAnnotation> list = annotations != null ? Arrays.asList(annotations) : getAnnotations();
PsiNameHelper.appendAnnotations(buffer, list, true);
}
buffer.append(aClass.getName());
PsiNameHelper.appendTypeArgs(buffer, getTypeParameters(), true, annotated);
return buffer.toString();
}
else if (target instanceof PsiPackage) {
return ((PsiPackage)target).getQualifiedName();
@@ -293,6 +305,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
LOG.assertTrue(target == null, target);
return getNormalizedText();
}
case PACKAGE_NAME_KIND:
case CLASS_FQ_NAME_KIND:
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
@@ -327,7 +340,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
if (incompleteCode && result.length == 0 && kind != CLASS_FQ_NAME_KIND && kind != CLASS_FQ_OR_PACKAGE_NAME_KIND) {
VariableResolverProcessor processor = new VariableResolverProcessor(referenceElement, containingFile);
PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, incompleteCode);
PsiScopesUtil.resolveAndWalk(processor, referenceElement, null, true);
result = processor.getResult();
if (result.length == 0 && kind == CLASS_NAME_KIND) {
result = referenceElement.resolve(PACKAGE_NAME_KIND, containingFile);
@@ -457,16 +470,16 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
case CLASS_FQ_OR_PACKAGE_NAME_KIND:
case CLASS_OR_PACKAGE_NAME_KIND: {
int classKind = kind == CLASS_OR_PACKAGE_NAME_KIND ? CLASS_NAME_KIND : CLASS_FQ_NAME_KIND;
JavaResolveResult[] result = resolve(classKind,containingFile);
JavaResolveResult[] result = resolve(classKind, containingFile);
if (result.length == 1 && !result[0].isAccessible()) {
JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND,containingFile);
JavaResolveResult[] packageResult = resolve(PACKAGE_NAME_KIND, containingFile);
if (packageResult.length != 0) {
result = packageResult;
}
}
else if (result.length == 0) {
result = resolve(PACKAGE_NAME_KIND,containingFile);
result = resolve(PACKAGE_NAME_KIND, containingFile);
}
return result;
@@ -607,7 +620,12 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
for (PsiAnnotation annotation : annotations) {
if (annotation.getParent() != newParent) {
newParent.addAfter(annotation, anchor);
if (anchor != null) {
newParent.addAfter(annotation, anchor);
}
else {
newParent.add(annotation);
}
annotation.delete();
}
}
@@ -935,7 +953,6 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
final PsiReferenceParameterList parameterList = getParameterList();
if (parameterList == null) return PsiType.EMPTY_ARRAY;
return parameterList.getTypeArguments();
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -131,7 +131,7 @@ public class JavaTreeGenerator implements TreeGenerator {
type = PsiType.getJavaLangObject(manager, GlobalSearchScope.projectScope(manager.getProject()));
}
String text = type.getPresentableText();
String text = type.getCanonicalText(true);
PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(original.getProject()).getParserFacade();
PsiTypeElement element = parserFacade.createTypeElementFromText(text, original);
@@ -157,14 +157,14 @@ class ParenthTest<T extends TZ> {
class TestWildcardInference {
interface A<T> {
}
class B<V> implements A<V> {
B(C<V> v) {
}
}
class C<E> {}
class U {
void foo() {
C<? extends Number> x = null;
@@ -202,13 +202,13 @@ class Another {
System.out.println(i);
<error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error>
<error descr="Incompatible types. Found: 'Outer2.Inner2<java.lang.String>', required: 'Outer2<java.lang.Integer>.Inner2<java.lang.String>'">Outer2<Integer>.Inner2<String> i5 = new Outer2<>().new Inner2<>();</error>
}
static Outer m() {return null;}
static <T extends Outer> T m1() {return null;}
static <T> T m2() {return null;}
}
class TypeParamsExtendsList {
@@ -40,6 +40,6 @@ class AAmbiguous {
}
public static void main(Promise<String> helloWorld) {
helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String,Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String,Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>;
helloWorld.then<error descr="Ambiguous method call: both 'Promise.then(Function<? super String, Promise<Integer>>)' and 'Promise.then(AsyncFunction<? super String, Promise<Integer>>)' match">(AAmbiguous::calculateLength)</error>;
}
}
@@ -21,9 +21,9 @@ class Test {
}
void foo(Foo<String> as, final Foo<Character> ac) {
boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> false)</error>);
String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>);
boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character,Boolean>)' and 'Foo.forAll(II<Character,String>)' match">(c -> "")</error>);
boolean b1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> false)</error>);
String s1 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
boolean b2 = as.forAll(s -> ac.forAll<error descr="Ambiguous method call: both 'Foo.forAll(I<Character, Boolean>)' and 'Foo.forAll(II<Character, String>)' match">(c -> "")</error>);
String s2 = as.forAll2(s -> ac.forAll2(<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
boolean b3 = as.forAll((I<String, Boolean>)s -> ac.forAll((I<Character, Boolean>)<error descr="Incompatible return type String in lambda expression">c -> ""</error>));
String s3 = as.forAll((II<String, String>)s -> ac.forAll((II<Character, String>)<error descr="Incompatible return type boolean in lambda expression">c -> false</error>));
@@ -53,7 +53,7 @@ class Test {
Test s1 = staticCall(Test::n0);
Test s2 = staticCall(Test::n1);
Test s3 = staticCall<error descr="Cannot resolve method 'staticCall(<method reference>)'">(Test::n2)</error>;
Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n01)</error>;
Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n012)</error>;
Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n01)</error>;
Test s5 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test, String>)' match">(Test::n012)</error>;
}
}
@@ -0,0 +1,5 @@
public class Bar {
public String doIt() {
return "";
}
}
@@ -1,15 +1,12 @@
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Target({TYPE_USE}) @interface TA { }
import pkg.TA;
class Outer {
class Middle {
class Inner {
void m1(Outer.Middle.Inner p) { }
void m2(@TA Outer.Middle.Inner p) { }
void m3(Outer.@TA Middle.Inner p) { }
void m4(Outer.Middle.@TA @TA Inner p) { }
void m2(@pkg.TA Outer.Middle.Inner p) { }
void m3(Outer.@pkg.TA Middle.Inner p) { }
void m4(Outer.Middle.@pkg.TA @pkg.TA Inner p) { }
}
}
}
@@ -1,7 +1,4 @@
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Target({TYPE_USE}) @interface TA { }
import pkg.TA;
class Outer {
class Middle {
@@ -0,0 +1,6 @@
package pkg;
import java.lang.annotation.*;
@Target({ElementType.TYPE_USE})
@interface TA { }
@@ -2,6 +2,6 @@ import util.Pair;
class Client {
void method() {
Pair<String, Pair<Integer,Boolean>> p = PairProvider.getPair();
Pair<String, Pair<Integer, Boolean>> p = PairProvider.getPair();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -15,15 +15,22 @@
*/
package com.intellij.codeInsight.psi
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.pom.java.LanguageLevel
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiImmediateClassType
import com.intellij.testFramework.LightIdeaTestCase
@SuppressWarnings(["GrUnresolvedAccess", "GroovyAssignabilityCheck"])
@SuppressWarnings("GroovyAssignabilityCheck")
class AnnotatedTypeTest extends LightIdeaTestCase {
private PsiFile context
private PsiElementFactory factory
public void setUp() throws Exception {
super.setUp()
factory = javaFacade.elementFactory
context = createFile("typeCompositionTest.java", """
package pkg;
public void testTypeComposition() {
PsiFile context = createFile("typeCompositionTest.java", """
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@@ -33,31 +40,55 @@ import static java.lang.annotation.ElementType.*;
class E1 extends Exception { }
class E2 extends Exception { }
""")
PsiElement psi
psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) int @TA(2) [] a", context)
assertEquals("@TA(1) int @TA(2) []", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context)
assertEquals("@TA(1) E1 | @TA(2) E2", psi.catchBlockParameters[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String @TA(2) [] f @TA(3) []", context)
assertEquals("@TA(1) String @TA(2) [] @TA(3) []", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("Class<@TA(1) ?> c", context)
assertEquals("Class<@TA(1) ?>", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("Class<@TA String> cs = new Class<>()", context)
assertEquals("Class<@TA String>", psi.declaredElements[0].initializer.type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("@A @TA(1) String s", context)
assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("@A java.lang.@TA(1) String s", context)
assertEquals("@TA(1) String", psi.declaredElements[0].type.presentableText)
psi = javaFacade.elementFactory.createStatementFromText("Collection<? extends> s", context)
assertEquals("Collection<?>", psi.declaredElements[0].type.presentableText)
}
public void testPrimitiveArrayType() {
doTest("@A @TA(1) int @TA(2) [] a", "@pkg.TA(1) int @pkg.TA(2) []", "int[]")
}
public void testEllipsisType() {
def psi = factory.createParameterFromText("@TA int @TA ... p", context)
assertTypeText(psi.type, "@pkg.TA int @pkg.TA ...", "int...")
}
public void testClassReferenceType() {
doTest("@A @TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String")
doTest("@A java.lang.@TA(1) String s", "java.lang.@pkg.TA(1) String", "java.lang.String")
}
public void testCStyleArrayType() {
doTest("@A @TA(1) String @TA(2) [] f @TA(3) []", "java.lang.@pkg.TA(1) String @pkg.TA(2) [] @pkg.TA(3) []", "java.lang.String[][]")
}
public void testWildcardType() {
doTest("Class<@TA(1) ?> c", "java.lang.Class<@pkg.TA(1) ?>", "java.lang.Class<?>")
}
public void testDisjunctionType() {
def psi = factory.createStatementFromText("try { } catch (@A @TA(1) E1 | @TA(2) E2 e) { }", context)
assertTypeText(psi.catchBlockParameters[0].type, "pkg.@pkg.TA(1) E1 | pkg.@pkg.TA(2) E2", "pkg.E1 | pkg.E2")
}
public void testDiamondType() {
def psi = factory.createStatementFromText("Class<@TA String> cs = new Class<>()", context)
assertTypeText(psi.declaredElements[0].initializer.type, "java.lang.Class<java.lang.@pkg.TA String>", "java.lang.Class<java.lang.String>")
}
public void testImmediateClassType() {
def aClass = javaFacade.findClass(CommonClassNames.JAVA_LANG_OBJECT)
def statement = factory.createStatementFromText("@TA int x", context)
def annotations = statement.declaredElements[0].modifierList.annotations
def type = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY, LanguageLevel.JDK_1_8, annotations)
assertTypeText(type, "java.lang.@pkg.TA Object", CommonClassNames.JAVA_LANG_OBJECT)
}
private void doTest(String text, String annotated, String canonical) {
def psi = factory.createStatementFromText(text, context)
assertTypeText(psi.declaredElements[0].type, annotated, canonical)
}
private static void assertTypeText(PsiType type, String annotated, String canonical) {
assert type.getCanonicalText(true) == annotated
assert type.getCanonicalText(false) == canonical
}
}
@@ -0,0 +1,54 @@
/*
* 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.openapi.editor.impl;
import com.intellij.openapi.fileEditor.FileEditorManagerTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import org.jdom.JDOMException;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
/**
* @author Dmitry Avdeev
*/
public class JavaFileEditorManagerTest extends FileEditorManagerTestCase {
public void testAsyncOpening() throws JDOMException, ExecutionException, InterruptedException, IOException {
openFiles("<component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
" <file leaf-file-name=\"Bar.java\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/Bar.java\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state vertical-scroll-proportion=\"0.032882012\" vertical-offset=\"0\" max-vertical-offset=\"517\">\n" +
" <caret line=\"1\" column=\"26\" selection-start=\"45\" selection-end=\"45\" />\n" +
" <folding>\n" +
" <element signature=\"e#69#70#0\" expanded=\"true\" />\n" +
" </folding>\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" </leaf>\n" +
" </component>");
}
@Override
protected String getTestDataPath() {
return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/java/java-tests/testData/fileEditorManager";
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -61,6 +61,7 @@ public class ShortenClassReferencesTest extends LightCodeInsightFixtureTestCase
public void testSCR37254() { doTest(); }
public void testTypeAnnotatedRef() {
myFixture.configureByFile("pkg/TA.java");
doTest();
for (PsiParameter parameter : PsiTreeUtil.findChildrenOfType(myFixture.getFile(), PsiParameter.class)) {
PsiTypeElement typeElement = parameter.getTypeElement();
@@ -0,0 +1,2 @@
org.jetbrains.jps.builders.impl.java.JavacCompilerTool
org.jetbrains.jps.builders.impl.java.EclipseCompilerTool
@@ -0,0 +1,89 @@
/*
* 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 org.jetbrains.jps.builders.impl.java;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
import javax.tools.*;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;
/**
* @author nik
*/
public class EclipseCompilerTool extends JavaCompilingTool {
@NotNull
@Override
public String getId() {
return JavaCompilers.ECLIPSE_ID;
}
@Nullable
@Override
public String getAlternativeId() {
return JavaCompilers.ECLIPSE_EMBEDDED_ID;
}
@NotNull
@Override
public String getDescription() {
return "Eclipse compiler";
}
@NotNull
@Override
public JavaCompiler createCompiler() throws CannotCreateJavaCompilerException {
for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) {
if ("EclipseCompiler".equals(StringUtil.getShortName(javaCompiler.getClass()))) {
return javaCompiler;
}
}
throw new CannotCreateJavaCompilerException("Eclipse Batch Compiler was not found in classpath");
}
@NotNull
@Override
public List<File> getAdditionalClasspath() {
for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler
final File compilerResource = ClasspathBootstrap.getResourceFile(javaCompiler.getClass());
final String name = compilerResource.getName();
if (name.startsWith("ecj-") && name.endsWith(".jar")) {
return Collections.singletonList(compilerResource);
}
}
return Collections.emptyList();
}
@Override
public void processCompilerOptions(@NotNull CompileContext context, @NotNull List<String> options) {
for (String option : options) {
if (option.startsWith("-proceedOnError")) {
Utils.PROCEED_ON_ERROR_KEY.set(context, Boolean.TRUE);
break;
}
}
}
}
@@ -0,0 +1,77 @@
/*
* 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 org.jetbrains.jps.builders.impl.java;
import com.intellij.util.ExceptionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.javac.JavacMain;
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
import javax.tools.*;
import java.io.File;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
public class JavacCompilerTool extends JavaCompilingTool {
@NotNull
@Override
public String getId() {
return JavaCompilers.JAVAC_ID;
}
@Nullable
@Override
public String getAlternativeId() {
return JavaCompilers.JAVAC_API_ID;
}
@NotNull
@Override
public String getDescription() {
return "javac " + System.getProperty("java.version");
}
@NotNull
@Override
public JavaCompiler createCompiler() throws CannotCreateJavaCompilerException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler != null) {
return compiler;
}
String message = "System Java Compiler was not found in classpath";
// trying to obtain additional diagnostic for the case when compiler.jar is present, but there were problems with compiler class loading:
try {
Class.forName("com.sun.tools.javac.api.JavacTool", false, JavacMain.class.getClassLoader());
}
catch (Throwable ex) {
message = message + ":\n" + ExceptionUtil.getThrowableText(ex);
}
throw new CannotCreateJavaCompilerException(message);
}
@NotNull
@Override
public List<File> getAdditionalClasspath() {
return Collections.emptyList();
}
}
@@ -0,0 +1,25 @@
/*
* 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 org.jetbrains.jps.builders.java;
/**
* @author nik
*/
public class CannotCreateJavaCompilerException extends Exception {
public CannotCreateJavaCompilerException(String message) {
super(message);
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.BuildRootIndex;
@@ -38,6 +39,7 @@ import org.jetbrains.jps.model.library.JpsTypedLibrary;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.library.sdk.JpsSdkReference;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.service.JpsServiceManager;
import java.io.File;
import java.io.IOException;
@@ -281,6 +283,16 @@ public class JavaBuilderUtil {
return sdkLibrary.getProperties();
}
@Nullable
public static JavaCompilingTool findCompilingTool(@NotNull String compilerId) {
for (JavaCompilingTool tool : JpsServiceManager.getInstance().getExtensions(JavaCompilingTool.class)) {
if (compilerId.equals(tool.getId()) || compilerId.equals(tool.getAlternativeId())) {
return tool;
}
}
return null;
}
private static class ModulesBasedFileFilter implements Mappings.DependentFilesFilter {
private final CompileContext myContext;
private final Set<JpsModule> myChunkModules;
@@ -0,0 +1,49 @@
/*
* 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 org.jetbrains.jps.builders.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.incremental.CompileContext;
import javax.tools.*;
import java.io.File;
import java.util.List;
/**
* @author nik
*/
public abstract class JavaCompilingTool {
@NotNull
public abstract String getId();
@Nullable
public String getAlternativeId() {
return null;
}
@NotNull
public abstract String getDescription();
@NotNull
public abstract JavaCompiler createCompiler() throws CannotCreateJavaCompilerException;
@NotNull
public abstract List<File> getAdditionalClasspath();
public void processCompilerOptions(@NotNull CompileContext context, @NotNull List<String> options) {
}
}
@@ -32,15 +32,14 @@ import net.n3.nanoxml.IXMLBuilder;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.ClassWriter;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceTransformer;
import org.jetbrains.jps.javac.JavacServer;
import org.jetbrains.jps.model.JpsModel;
import org.jetbrains.jps.model.impl.JpsModelImpl;
import org.jetbrains.jps.model.serialization.JpsProjectLoader;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.*;
import java.io.File;
import java.lang.reflect.Method;
import java.util.*;
@@ -177,7 +176,7 @@ public class ClasspathBootstrap {
}
}
public static List<File> getJavacServerClasspath(String sdkHome, boolean useEclipseCompiler) {
public static List<File> getJavacServerClasspath(String sdkHome, JavaCompilingTool compilingTool) {
final Set<File> cp = new LinkedHashSet<File>();
cp.add(getResourceFile(JavacServer.class)); // self
// util
@@ -236,16 +235,7 @@ public class ClasspathBootstrap {
}
}
if (useEclipseCompiler) {
// eclipse compiler
for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler
final File compilerResource = getResourceFile(javaCompiler.getClass());
final String name = compilerResource.getName();
if (name.startsWith("ecj-") && name.endsWith(".jar")) {
cp.add(compilerResource);
}
}
}
cp.addAll(compilingTool.getAdditionalClasspath());
final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class;
final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader());
@@ -39,6 +39,7 @@ import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.FileProcessor;
import org.jetbrains.jps.builders.java.JavaBuilderExtension;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
@@ -81,7 +82,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
public static final boolean USE_EMBEDDED_JAVAC = System.getProperty(GlobalOptions.USE_EXTERNAL_JAVAC_OPTION) == null;
private static final Key<Integer> JAVA_COMPILER_VERSION_KEY = Key.create("_java_compiler_version_");
public static final Key<Boolean> IS_ENABLED = Key.create("_java_compiler_enabled_");
private static final Key<Boolean> IS_COMPILER_API_SUPPORTED = Key.create("_java_compiler_api_supported_");
private static final Key<JavaCompilingTool> COMPILING_TOOL = Key.create("_java_compiling_tool_");
private static final Key<AtomicReference<String>> COMPILER_VERSION_INFO = Key.create("_java_compiler_version_info_");
private static final Set<String> FILTERED_OPTIONS = new HashSet<String>(Arrays.<String>asList(
@@ -137,16 +138,9 @@ public class JavaBuilder extends ModuleLevelBuilder {
if (LOG.isDebugEnabled()) {
LOG.debug("Java compiler ID: " + compilerId);
}
final boolean isJavac = JavaCompilers.JAVAC_ID.equalsIgnoreCase(compilerId) || JavaCompilers.JAVAC_API_ID.equalsIgnoreCase(compilerId);
final boolean isEclipse = JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId) || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
IS_COMPILER_API_SUPPORTED.set(context, isJavac || isEclipse);
String messageText = null;
if (isJavac) {
messageText = "Using javac " + System.getProperty("java.version") + " to compile java sources";
}
else if (isEclipse) {
messageText = "Using eclipse compiler to compile java sources";
}
JavaCompilingTool compilingTool = JavaBuilderUtil.findCompilingTool(compilerId);
COMPILING_TOOL.set(context, compilingTool);
String messageText = compilingTool != null ? "Using " + compilingTool.getDescription() + " to compile java sources" : null;
COMPILER_VERSION_INFO.set(context, new AtomicReference<String>(messageText));
}
@@ -159,16 +153,17 @@ public class JavaBuilder extends ModuleLevelBuilder {
@NotNull ModuleChunk chunk,
@NotNull DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
@NotNull OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
if (!IS_ENABLED.get(context, Boolean.TRUE) || !IS_COMPILER_API_SUPPORTED.get(context, Boolean.TRUE)) {
JavaCompilingTool compilingTool = COMPILING_TOOL.get(context);
if (!IS_ENABLED.get(context, Boolean.TRUE) || compilingTool == null) {
return ExitCode.NOTHING_DONE;
}
return doBuild(context, chunk, dirtyFilesHolder, outputConsumer);
return doBuild(context, chunk, dirtyFilesHolder, outputConsumer, compilingTool);
}
public ExitCode doBuild(@NotNull CompileContext context,
@NotNull ModuleChunk chunk,
@NotNull DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
@NotNull OutputConsumer outputConsumer) throws ProjectBuildException, IOException {
@NotNull OutputConsumer outputConsumer, JavaCompilingTool compilingTool) throws ProjectBuildException, IOException {
try {
final Set<File> filesToCompile = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
@@ -190,7 +185,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer);
return compile(context, chunk, dirtyFilesHolder, filesToCompile, outputConsumer, compilingTool);
}
catch (BuildDataCorruptedException e) {
throw e;
@@ -224,7 +219,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
ModuleChunk chunk,
DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget> dirtyFilesHolder,
Collection<File> files,
OutputConsumer outputConsumer)
OutputConsumer outputConsumer, @NotNull JavaCompilingTool compilingTool)
throws Exception {
ExitCode exitCode = ExitCode.NOTHING_DONE;
@@ -284,7 +279,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
try {
compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink);
compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink, compilingTool);
}
finally {
// heuristic: incorrect paths data recovery, so that the next make should not contain non-existing sources in 'recompile' list
@@ -328,7 +323,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
Collection<File> platformCp,
Collection<File> sourcePath,
DiagnosticOutputConsumer diagnosticSink,
final OutputFileConsumer outputSink) throws Exception {
final OutputFileConsumer outputSink, JavaCompilingTool compilingTool) throws Exception {
final TasksCounter counter = new TasksCounter();
COUNTER_KEY.set(context, counter);
@@ -372,7 +367,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
final Map<File, Set<File>> outs = buildOutputDirectoriesMap(context, chunk);
final List<String> options = getCompilationOptions(context, chunk, profile);
final List<String> options = getCompilationOptions(context, chunk, profile, compilingTool);
final ClassProcessingConsumer classesConsumer = new ClassProcessingConsumer(context, outputSink);
if (LOG.isDebugEnabled()) {
LOG.debug("Compiling chunk [" + chunk.getName() + "] with options: \"" + StringUtil.join(options, " ") + "\"");
@@ -380,13 +375,11 @@ public class JavaBuilder extends ModuleLevelBuilder {
try {
final boolean rc;
if (USE_EMBEDDED_JAVAC) {
final boolean useEclipse = useEclipseCompiler(context);
rc = JavacMain.compile(
options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer, context.getCancelStatus(), useEclipse
);
rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer,
context.getCancelStatus(), compilingTool);
}
else {
final JavacServerClient client = ensureJavacServerLaunched(context);
final JavacServerClient client = ensureJavacServerLaunched(context, compilingTool);
final RequestFuture<JavacServerResponseHandler> future = client.sendCompileRequest(
options, files, classpath, platformCp, sourcePath, outs, diagnosticSink, classesConsumer
);
@@ -404,13 +397,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
private static boolean useEclipseCompiler(CompileContext context) {
JpsProject project = context.getProjectDescriptor().getProject();
final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project);
final String compilerId = configuration != null? configuration.getJavaCompilerId() : null;
return JavaCompilers.ECLIPSE_ID.equalsIgnoreCase(compilerId) || JavaCompilers.ECLIPSE_EMBEDDED_ID.equalsIgnoreCase(compilerId);
}
private void submitAsyncTask(final CompileContext context, final Runnable taskRunnable) {
final TasksCounter counter = COUNTER_KEY.get(context);
@@ -432,7 +418,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
});
}
private static synchronized JavacServerClient ensureJavacServerLaunched(CompileContext context) throws Exception {
private static synchronized JavacServerClient ensureJavacServerLaunched(@NotNull CompileContext context, @NotNull JavaCompilingTool compilingTool) throws Exception {
final ExternalJavacDescriptor descriptor = ExternalJavacDescriptor.KEY.get(context);
if (descriptor != null) {
return descriptor.client;
@@ -445,7 +431,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
final String javaHome = SystemProperties.getJavaHome();
final BaseOSProcessHandler processHandler = JavacServerBootstrap.launchJavacServer(
javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context), useEclipseCompiler(context)
javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context, compilingTool), compilingTool
);
final JavacServerClient client = new JavacServerClient();
try {
@@ -529,19 +515,22 @@ public class JavaBuilder extends ModuleLevelBuilder {
private static final Key<List<String>> JAVAC_VM_OPTIONS = Key.create("_javac_vm_options_");
private static final Key<String> USER_DEFINED_BYTECODE_TARGET = Key.create("_user_defined_bytecode_target_");
private static List<String> getCompilationVMOptions(CompileContext context) {
private static List<String> getCompilationVMOptions(CompileContext context, JavaCompilingTool compilingTool) {
List<String> cached = JAVAC_VM_OPTIONS.get(context);
if (cached == null) {
loadCommonJavacOptions(context);
loadCommonJavacOptions(context, compilingTool);
cached = JAVAC_VM_OPTIONS.get(context);
}
return cached;
}
private static List<String> getCompilationOptions(CompileContext context, ModuleChunk chunk, @Nullable ProcessorConfigProfile profile) {
private static List<String> getCompilationOptions(CompileContext context,
ModuleChunk chunk,
@Nullable ProcessorConfigProfile profile,
@NotNull JavaCompilingTool compilingTool) {
List<String> cached = JAVAC_OPTIONS.get(context);
if (cached == null) {
loadCommonJavacOptions(context);
loadCommonJavacOptions(context, compilingTool);
cached = JAVAC_OPTIONS.get(context);
assert cached != null : context;
}
@@ -701,7 +690,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
return javaVersion;
}
private static void loadCommonJavacOptions(CompileContext context) {
private static void loadCommonJavacOptions(@NotNull CompileContext context, @NotNull JavaCompilingTool compilingTool) {
final List<String> options = new ArrayList<String>();
final List<String> vmOptions = new ArrayList<String>();
@@ -755,14 +744,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
if (useEclipseCompiler(context)) {
for (String option : options) {
if (option.startsWith("-proceedOnError")) {
Utils.PROCEED_ON_ERROR_KEY.set(context, Boolean.TRUE);
break;
}
}
}
compilingTool.processCompilerOptions(context, options);
JAVAC_OPTIONS.set(context, options);
JAVAC_VM_OPTIONS.set(context, vmOptions);
@@ -16,11 +16,13 @@
package org.jetbrains.jps.javac;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.impl.java.JavacCompilerTool;
import org.jetbrains.jps.builders.java.CannotCreateJavaCompilerException;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.builders.java.JavaSourceTransformer;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.incremental.LineOutputWriter;
@@ -57,52 +59,29 @@ public class JavacMain {
Map<File, Set<File>> outputDirToRoots,
final DiagnosticOutputConsumer diagnosticConsumer,
final OutputFileConsumer outputSink,
CanceledStatus canceledStatus, boolean useEclipseCompiler) {
JavaCompiler compiler = null;
if (useEclipseCompiler) {
for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) {
compiler = javaCompiler;
break;
}
if (compiler == null) {
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Eclipse Batch Compiler was not found in classpath"));
return false;
}
CanceledStatus canceledStatus, @NotNull JavaCompilingTool compilingTool) {
JavaCompiler compiler;
try {
compiler = compilingTool.createCompiler();
}
final boolean nowUsingJavac;
if (compiler == null) {
compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
String message = "System Java Compiler was not found in classpath";
// trying to obtain additional diagnostic for the case when compiler.jar is present, but there were problems with compiler class loading:
try {
Class.forName("com.sun.tools.javac.api.JavacTool", false, JavacMain.class.getClassLoader());
}
catch (Throwable ex) {
message = message + ":\n" + ExceptionUtil.getThrowableText(ex);
}
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, message));
return false;
}
nowUsingJavac = true;
}
else {
nowUsingJavac = false;
catch (CannotCreateJavaCompilerException e) {
diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
return false;
}
for (File outputDir : outputDirToRoots.keySet()) {
outputDir.mkdirs();
}
final List<JavaSourceTransformer> transformers = getSourceTransformers();
final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, diagnosticConsumer, outputSink, canceledStatus, nowUsingJavac), transformers);
final boolean usingJavac = compilingTool instanceof JavacCompilerTool;
final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, diagnosticConsumer, outputSink, canceledStatus, usingJavac), transformers);
fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-endorseddirs", Collections.singleton("").iterator()); // this will clear cached stuff
final Collection<String> _options = prepareOptions(options, nowUsingJavac);
final Collection<String> _options = prepareOptions(options, usingJavac);
try {
fileManager.setOutputDirectories(outputDirToRoots);
@@ -115,7 +94,7 @@ public class JavacMain {
if (!classpath.isEmpty()) {
try {
fileManager.setLocation(StandardLocation.CLASS_PATH, classpath);
if (!nowUsingJavac && !isOptionSet(options, "-processorpath")) {
if (!usingJavac && !isOptionSet(options, "-processorpath")) {
// for non-javac file manager ensure annotation processor path defaults to classpath
fileManager.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, classpath);
}
@@ -148,7 +127,7 @@ public class JavacMain {
//noinspection IOResourceOpenedButNotSafelyClosed
final LineOutputWriter out = new LineOutputWriter() {
protected void lineAvailable(String line) {
if (nowUsingJavac) {
if (usingJavac) {
diagnosticConsumer.outputLineAvailable(line);
}
else {
@@ -186,7 +165,7 @@ public class JavacMain {
}
finally {
fileManager.close();
if (nowUsingJavac) {
if (usingJavac) {
cleanupJavacNameTable();
}
}
@@ -29,6 +29,9 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.util.concurrent.ImmediateEventExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.impl.java.JavacCompilerTool;
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.service.SharedThreadPool;
import javax.tools.*;
@@ -44,7 +47,7 @@ public class JavacServer {
public static final int DEFAULT_SERVER_PORT = 7878;
public static final String SERVER_SUCCESS_START_MESSAGE = "Javac server started successfully. Listening on port: ";
public static final String SERVER_ERROR_START_MESSAGE = "Error starting Javac Server: ";
public static final String USE_ECLIPSE_COMPILER_PROPERTY = "use.eclipse.compiler";
public static final String JPS_JAVA_COMPILING_TOOL_PROPERTY = "jps.java.compiling.tool";
private ChannelRegistrar myChannelRegistrar;
@@ -153,7 +156,8 @@ public class JavacServer {
};
try {
final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, System.getProperty(USE_ECLIPSE_COMPILER_PROPERTY) != null);
JavaCompilingTool tool = getCompilingTool();
final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, tool);
return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc));
}
catch (Throwable e) {
@@ -163,6 +167,17 @@ public class JavacServer {
}
}
private static JavaCompilingTool getCompilingTool() {
String property = System.getProperty(JPS_JAVA_COMPILING_TOOL_PROPERTY);
if (property != null) {
JavaCompilingTool tool = JavaBuilderUtil.findCompilingTool(property);
if (tool != null) {
return tool;
}
}
return new JavacCompilerTool();
}
private final Set<CancelHandler> myCancelHandlers = Collections.synchronizedSet(new HashSet<CancelHandler>());
public void cancelBuilds() {
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.concurrency.Semaphore;
import org.jetbrains.jps.builders.java.JavaCompilingTool;
import org.jetbrains.jps.cmdline.ClasspathBootstrap;
import org.jetbrains.jps.service.SharedThreadPool;
@@ -44,7 +45,7 @@ public class JavacServerBootstrap {
int port,
File workingDir,
List<String> vmOptions,
boolean useEclipseCompiler) throws Exception {
JavaCompilingTool compilingTool) throws Exception {
final List<String> cmdLine = new ArrayList<String>();
appendParam(cmdLine, getVMExecutablePath(sdkHomePath));
appendParam(cmdLine, "-XX:MaxPermSize=150m");
@@ -82,9 +83,7 @@ public class JavacServerBootstrap {
appendParam(cmdLine, "-Duser.region=" + region);
}
if (useEclipseCompiler) {
appendParam(cmdLine, "-D" + JavacServer.USE_ECLIPSE_COMPILER_PROPERTY);
}
appendParam(cmdLine, "-D" + JavacServer.JPS_JAVA_COMPILING_TOOL_PROPERTY + "=" + compilingTool.getId());
// this will disable standard extensions to ensure javac is loaded from the right tools.jar
appendParam(cmdLine, "-Djava.ext.dirs=");
@@ -95,7 +94,7 @@ public class JavacServerBootstrap {
appendParam(cmdLine, "-classpath");
final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath, useEclipseCompiler);
final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath, compilingTool);
final StringBuilder classpath = new StringBuilder();
for (File file : cp) {
if (classpath.length() > 0) {
@@ -156,17 +155,15 @@ public class JavacServerBootstrap {
public void onTextAvailable(ProcessEvent event, Key outputType) {
if (outputType == ProcessOutputTypes.STDERR) {
try {
final String text = event.getText();
if (text != null) {
if (text.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE) || text.contains(JavacServer.SERVER_ERROR_START_MESSAGE)) {
processHandler.removeProcessListener(this);
serverStartMessage.set(text);
}
final String text = event.getText();
if (text != null && (text.contains(JavacServer.SERVER_SUCCESS_START_MESSAGE) || text.contains(JavacServer.SERVER_ERROR_START_MESSAGE))) {
try {
processHandler.removeProcessListener(this);
serverStartMessage.set(text);
}
finally {
semaphore.up();
}
}
finally {
semaphore.up();
}
}
}
@@ -27,8 +27,8 @@ import org.jetbrains.annotations.NotNull;
*/
public class SegmentArray {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.ex.util.SegmentArray");
private int[] myStarts;
private int[] myEnds;
protected int[] myStarts;
protected int[] myEnds;
protected int mySegmentCount = 0;
protected static final int INITIAL_SIZE = 64;
@@ -84,26 +84,32 @@ public class SegmentArray {
return newArray;
}
protected int noSegmentsAvailable(int offset) {
throw new IllegalStateException("no segments available. offset = " + offset);
}
protected int offsetOutOfRange(int offset, int lastValidOffset) {
throw new IndexOutOfBoundsException("Wrong offset: " + offset + ". Should be in range: [0, " + lastValidOffset + "]");
}
public final int findSegmentIndex(int offset) {
if (mySegmentCount <= 0) {
if (offset == 0) return 0;
throw new IllegalStateException("no segments available. offset = "+offset);
return offset == 0 ? 0 : noSegmentsAvailable(offset);
}
final int lastValidOffset = getLastValidOffset();
if (offset > lastValidOffset || offset < 0) {
throw new IndexOutOfBoundsException("Wrong offset: " + offset + ". Should be in range: [0, " + lastValidOffset + "]");
return offsetOutOfRange(offset, lastValidOffset);
}
final int lastValidIndex = mySegmentCount - 1;
if (offset == lastValidOffset) return lastValidIndex;
int end = mySegmentCount - 1;
if (offset == lastValidOffset) {
return end;
}
int start = 0;
int end = lastValidIndex;
while (start < end) {
int i = (start + end) / 2;
while (start <= end) {
int i = (start + end) >>> 1;
if (offset < myStarts[i]) {
end = i - 1;
}
@@ -115,9 +121,12 @@ public class SegmentArray {
}
}
return segmentNotFound(offset, start);
}
protected int segmentNotFound(int offset, int start) {
// This means that there is a gap at given offset
assert myStarts[start] <= offset && offset < myEnds[start] : start;
return start;
}
@@ -184,17 +184,17 @@ public class DaemonListeners implements Disposable {
!worthBothering(editor.getDocument(), editor.getProject())) {
return; //no need to stop daemon if something happened in the console
}
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (!editor.getComponent().isShowing() && !application.isUnitTestMode() ||
myProject.isDisposed()) {
return;
if (!application.isUnitTestMode()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (!editor.getComponent().isShowing() || myProject.isDisposed()) {
return;
}
myDaemonCodeAnalyzer.hideLastIntentionHint();
}
myDaemonCodeAnalyzer.hideLastIntentionHint();
}
}, ModalityState.current());
}, ModalityState.current());
}
}
}, this);
@@ -39,7 +39,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.ui.LightweightHint;
import com.intellij.util.containers.WeakList;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -184,7 +183,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
@Override
public void releaseFoldings(@NotNull Editor editor) {
ApplicationManager.getApplication().assertIsDispatchThread();
ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent());
final Project project = editor.getProject();
if (project != null && (!project.equals(myProject) || !project.isOpen())) return;
@@ -217,32 +216,26 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
PsiDocumentManager.getInstance(myProject).commitDocument(document);
Runnable operation = new Runnable() {
Runnable runnable = updateFoldRegions(editor, true, true);
if (runnable != null) {
runnable.run();
}
if (myProject.isDisposed() || editor.isDisposed()) return;
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
Runnable runnable = updateFoldRegions(editor, true, true);
if (runnable != null) {
runnable.run();
DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document);
Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject);
for (Editor otherEditor : editors) {
if (otherEditor == editor) continue;
documentFoldingInfo.loadFromEditor(otherEditor);
break;
}
if (myProject.isDisposed() || editor.isDisposed()) return;
foldingModel.runBatchFoldingOperation(new Runnable() {
@Override
public void run() {
DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document);
Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject);
for (Editor otherEditor : editors) {
if (otherEditor == editor) continue;
documentFoldingInfo.loadFromEditor(otherEditor);
break;
}
documentFoldingInfo.setToEditor(editor);
documentFoldingInfo.setToEditor(editor);
documentFoldingInfo.clear();
}
});
documentFoldingInfo.clear();
}
};
UIUtil.invokeLaterIfNeeded(operation);
});
}
@Override
@@ -21,6 +21,7 @@ import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -38,7 +39,6 @@ import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.*;
class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
@@ -64,7 +64,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
}
void loadFromEditor(@NotNull Editor editor) {
assertDispatchThread();
assertDispatchThread(editor);
LOG.assertTrue(!editor.isDisposed());
clear();
@@ -95,12 +95,12 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState {
}
}
private static void assertDispatchThread() {
assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
private static void assertDispatchThread(@NotNull Editor editor) {
ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent());
}
void setToEditor(@NotNull final Editor editor) {
assertDispatchThread();
assertDispatchThread(editor);
final PsiManager psiManager = PsiManager.getInstance(myProject);
if (psiManager.isDisposed()) return;
@@ -16,11 +16,12 @@
package com.intellij.openapi.wm;
import com.intellij.openapi.ui.Painter;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.Painter;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.ui.update.UiNotifyConnector;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import javax.swing.*;
import java.awt.*;
@@ -69,6 +70,9 @@ public class IdeGlassPaneUtil {
public static boolean canBePreprocessed(MouseEvent e) {
Component c = SwingUtilities.getDeepestComponentAt(e.getComponent(), e.getX(), e.getY());
if (JBPopupFactory.getInstance().getParentBalloonFor(c) != null) {
return false;
}
if (c instanceof IdeGlassPane.TopComponent) {
return ((IdeGlassPane.TopComponent)c).canBePreprocessed(e);
@@ -273,6 +273,10 @@ public class DarculaLaf extends BasicLookAndFeel {
}
protected Object parseValue(String key, @NotNull String value) {
if ("null".equals(value)) {
return null;
}
if (key.endsWith("Insets")) {
final List<String> numbers = StringUtil.split(value, ",");
return new InsetsUIResource(Integer.parseInt(numbers.get(0)),
@@ -45,7 +45,6 @@ import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.List;
@@ -201,7 +200,6 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
}
private void runBatchFoldingOperation(final Runnable operation, final boolean dontCollapseCaret, final boolean moveCaret) {
LOG.assertTrue(SwingUtilities.isEventDispatchThread(), Thread.currentThread().toString());
assertIsDispatchThreadForEditor();
boolean oldDontCollapseCaret = myDoNotCollapseCaret;
myDoNotCollapseCaret |= dontCollapseCaret;
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
@@ -141,7 +142,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme
}
LOG.assertTrue(selectedEditor != null);
final int selectedProviderIndex = ArrayUtilRt.find(editors, selectedEditor);
LOG.assertTrue(selectedProviderIndex != -1);
LOG.assertTrue(selectedProviderIndex != -1, "Can't find " + selectedEditor + " among " + Arrays.asList(editors));
final HistoryEntry entry = getEntry(file);
if(entry != null){
@@ -83,7 +83,13 @@ public class SystemNotificationsImpl extends SystemNotifications implements Pers
}
}
catch (Throwable t) {
Logger.getInstance(SystemNotifications.class).warn(t);
Logger logger = Logger.getInstance(SystemNotifications.class);
if (logger.isDebugEnabled()) {
logger.debug(t);
}
else {
logger.info(t.getMessage());
}
}
return null;
@@ -67,9 +67,9 @@ public class SelectUnselectOccurrenceActionsTest extends LightPlatformCodeInsigh
"another text here");
executeSelectAllAction();
checkResult("some <selection>t<caret>ext</selection>\n" +
"some <selection>t<caret>ext</selection>s\n" +
"some <selection>t<caret>ext</selection>s\n" +
"another text here");
"some texts\n" +
"some texts\n" +
"another <selection>t<caret>ext</selection> here");
assertEquals(0, hintCount);
}
@@ -17,29 +17,20 @@ package com.intellij.openapi.fileEditor;
import com.intellij.ide.ui.UISettings;
import com.intellij.mock.Mock;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @author Dmitry Avdeev
@@ -77,17 +68,18 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase {
openFiles(" <component name=\"FileEditorManager\">\n" +
" <leaf>\n" +
" <file leaf-file-name=\"foo.xsd\" pinned=\"false\" current=\"true\" current-in-tab=\"true\">\n" +
" <entry selected=\"true\" file=\"file://$PROJECT_DIR$/src/1.txt\">\n" +
" <provider editor-type-id=\"mock\" selected=\"true\">\n" +
" <state />\n" +
" </provider>\n" +
" <provider editor-type-id=\"text-editor\">\n" +
" <state/>\n" +
" <file leaf-file-name=\"Bar.java\" pinned=\"false\" current=\"false\" current-in-tab=\"false\">\n" +
" <entry file=\"file://$PROJECT_DIR$/src/Bar.java\">\n" +
" <provider selected=\"true\" editor-type-id=\"text-editor\">\n" +
" <state vertical-scroll-proportion=\"0.0\" vertical-offset=\"0\" max-vertical-offset=\"187\">\n" +
" <caret line=\"1\" column=\"26\" selection-start=\"45\" selection-end=\"45\" />\n" +
" <folding>\n" +
" <element signature=\"e#69#70#0\" expanded=\"true\" />\n" +
" </folding>\n" +
" </state>\n" +
" </provider>\n" +
" </entry>\n" +
" </file>\n" +
" </leaf>\n" +
" </component>\n");
FileEditor[] selectedEditors = myManager.getSelectedEditors();
assertEquals(1, selectedEditors.length);
@@ -157,24 +149,6 @@ public class FileEditorManagerTest extends FileEditorManagerTestCase {
assertEquals(Arrays.asList(fileNames), names);
}
private void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException {
Document document = JDOMUtil.loadDocument(s);
Element rootElement = document.getRootElement();
ExpandMacroToPathMap map = new ExpandMacroToPathMap();
map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
map.substitute(rootElement, true, true);
myManager.readExternal(rootElement);
Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
myManager.getMainSplitters().openFiles();
}
});
future.get();
}
@Override
protected String getTestDataPath() {
return PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/fileEditorManager";
@@ -1,13 +1,27 @@
package com.intellij.openapi.fileEditor;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.ui.docking.DockManager;
import com.intellij.util.ui.UIUtil;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jetbrains.jps.model.serialization.PathMacroUtil;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* @author Dmitry Avdeev
@@ -40,4 +54,30 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
protected VirtualFile getFile(String path) {
return LocalFileSystem.getInstance().refreshAndFindFileByPath(getTestDataPath() + path);
}
protected void openFiles(String s) throws IOException, JDOMException, InterruptedException, ExecutionException {
Document document = JDOMUtil.loadDocument(s);
Element rootElement = document.getRootElement();
ExpandMacroToPathMap map = new ExpandMacroToPathMap();
map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
map.substitute(rootElement, true, true);
myManager.readExternal(rootElement);
Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
public void run() {
myManager.getMainSplitters().openFiles();
}
});
while (true) {
try {
future.get(100, TimeUnit.MILLISECONDS);
return;
}
catch (TimeoutException e) {
UIUtil.dispatchAllInvocationEvents();
}
}
}
}
@@ -1585,6 +1585,7 @@ public class UIUtil {
g.setComposite(X_RENDER_ACTIVE.getValue() ? AlphaComposite.SrcOver : AlphaComposite.Src);
}
/** @see #pump() */
@TestOnly
public static void dispatchAllInvocationEvents() {
assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
@@ -1604,6 +1605,7 @@ public class UIUtil {
}
}
/** @see #dispatchAllInvocationEvents() */
@TestOnly
public static void pump() {
assert !SwingUtilities.isEventDispatchThread();
@@ -115,7 +115,7 @@ public abstract class XDebuggerEvaluator {
* @param offset offset
* @param sideEffectsAllowed if this parameter is false, the expression should not have any side effects when evaluated
* (such expressions are evaluated in quick popups)
* @return pair of text range of expression (to display as link) and actual expression to evaluate (optional, could be null)
* @return pair of text range of expression (to highlight as link) and actual expression to evaluate (optional, could be null)
*/
@Nullable
public Pair<TextRange, String> getExpressionAtOffset(@NotNull Project project, @NotNull Document document, int offset, boolean sideEffectsAllowed) {
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
@@ -35,6 +36,19 @@ import org.jetbrains.annotations.Nullable;
public abstract class DebuggerSupport {
private static final ExtensionPointName<DebuggerSupport> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.debuggerSupport");
protected static final class DisabledActionHandler extends DebuggerActionHandler {
public static final DisabledActionHandler INSTANCE = new DisabledActionHandler();
@Override
public void perform(@NotNull Project project, AnActionEvent event) {
}
@Override
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
return false;
}
}
@NotNull
public static DebuggerSupport[] getDebuggerSupports() {
return Extensions.getExtensions(EXTENSION_POINT);
@@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class AddToWatchesAction extends XDebuggerActionBase {
final class AddToWatchesAction extends XDebuggerActionBase {
public AddToWatchesAction() {
super(true);
}
@@ -15,17 +15,18 @@
*/
package com.intellij.xdebugger.impl.actions;
import org.jetbrains.annotations.NotNull;
import com.intellij.xdebugger.impl.DebuggerSupport;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class EvaluateAction extends XDebuggerActionBase {
final class EvaluateAction extends XDebuggerActionBase {
public EvaluateAction() {
super(true);
}
@Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return debuggerSupport.getEvaluateHandler();
@@ -65,10 +65,14 @@ public class QuickEvaluateAction extends XDebuggerActionBase {
@Override
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
if (!myHandler.isEnabled(project)) return false;
if (!myHandler.isEnabled(project)) {
return false;
}
Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor == null) return false;
if (editor == null) {
return false;
}
InputEvent inputEvent = event.getInputEvent();
if (inputEvent instanceof MouseEvent && inputEvent.isAltDown()) {
@@ -20,7 +20,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,10 +42,10 @@ public class XAddToWatchesFromEditorActionHandler extends XDebuggerActionHandler
}
String text = editor.getSelectionModel().getSelectedText();
if (text == null && session.isSuspended()) {
final XStackFrame stackFrame = session.getCurrentStackFrame();
if (stackFrame != null) {
text = XDebuggerEvaluateActionHandler.getExpressionText(stackFrame.getEvaluator(), editor.getProject(), editor);
if (text == null) {
XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
if (evaluator != null) {
text = XDebuggerEvaluateActionHandler.getExpressionText(evaluator, editor.getProject(), editor);
}
}
@@ -28,7 +28,6 @@ import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
import com.intellij.xdebugger.impl.evaluate.XDebuggerEvaluationDialog;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import org.jetbrains.annotations.NotNull;
@@ -37,14 +36,15 @@ import org.jetbrains.annotations.Nullable;
/**
* @author nik
*/
public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHandler {
public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler {
@Override
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
XDebuggerEditorsProvider editorsProvider = session.getDebugProcess().getEditorsProvider();
XStackFrame stackFrame = session.getCurrentStackFrame();
if (stackFrame == null) return;
final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
if (evaluator == null) return;
final XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
if (evaluator == null) {
return;
}
@Nullable Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
@@ -64,7 +64,7 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHand
text = value.getEvaluationExpression();
}
}
new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, StringUtil.notNullize(text), stackFrame.getSourcePosition()).show();
new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, StringUtil.notNullize(text), stackFrame == null ? null : stackFrame.getSourcePosition()).show();
}
@Nullable
@@ -86,11 +86,6 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerSuspendedActionHand
@Override
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
if (!super.isEnabled(session, dataContext)) {
return false;
}
XStackFrame stackFrame = session.getCurrentStackFrame();
return stackFrame != null && stackFrame.getEvaluator() != null;
return session.getDebugProcess().getEvaluator() != null;
}
}
@@ -29,7 +29,6 @@ import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.EvaluationMode;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
@@ -38,6 +37,7 @@ import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.nodes.EvaluatingExpressionRootNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -61,10 +61,10 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
private final boolean myIsCodeFragmentEvaluationSupported;
public XDebuggerEvaluationDialog(@NotNull XDebugSession session,
final @NotNull XDebuggerEditorsProvider editorsProvider,
@NotNull XDebuggerEditorsProvider editorsProvider,
@NotNull XDebuggerEvaluator evaluator,
@NotNull String text,
final XSourcePosition sourcePosition) {
@Nullable XSourcePosition sourcePosition) {
super(session.getProject(), true);
mySession = session;
myEditorsProvider = editorsProvider;
@@ -212,8 +212,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
inputEditor.saveTextInHistory();
String expression = inputEditor.getText();
XStackFrame frame = mySession.getCurrentStackFrame();
XDebuggerEvaluator evaluator = frame == null ? null : frame.getEvaluator();
XDebuggerEvaluator evaluator = mySession.getDebugProcess().getEvaluator();
if (evaluator == null) {
evaluationCallback.errorOccurred(XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"));
}
@@ -26,7 +26,6 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
@@ -103,12 +102,9 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler {
public int getValueLookupDelay(final Project project) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
XStackFrame stackFrame = session.getCurrentStackFrame();
if (stackFrame != null) {
XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
if (evaluator != null) {
return evaluator.getValuePopupDelay();
}
XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
if (evaluator != null) {
return evaluator.getValuePopupDelay();
}
}
return 700;
@@ -16,6 +16,10 @@
package com.intellij.xdebugger.impl.evaluate.quick;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.console.LanguageConsoleView;
import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
@@ -72,7 +76,17 @@ public class XValueHint extends AbstractValueHint {
myEvaluator = evaluator;
myDebugSession = session;
myExpression = XDebuggerEvaluateActionHandler.getExpressionText(expressionData, editor.getDocument());
final VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument());
VirtualFile file;
ConsoleView consoleView = ConsoleViewImpl.CONSOLE_VIEW_IN_EDITOR_VIEW.get(editor);
if (consoleView instanceof LanguageConsoleView) {
LanguageConsoleImpl console = ((LanguageConsoleView)consoleView).getConsole();
file = console.getHistoryViewer() == editor ? console.getVirtualFile() : null;
}
else {
file = FileDocumentManager.getInstance().getFile(editor.getDocument());
}
myExpressionPosition = file != null ? XDebuggerUtil.getInstance().createPositionByOffset(file, expressionData.first.getStartOffset()) : null;
}
@@ -123,8 +123,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
@Override
public void addWatchExpression(@NotNull String expression, int index, final boolean navigateToWatchNode) {
XStackFrame stackFrame = mySession.getCurrentStackFrame();
myRootNode.addWatchExpression(stackFrame == null ? null : stackFrame.getEvaluator(), expression, index, navigateToWatchNode);
myRootNode.addWatchExpression(mySession.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode);
updateSessionData();
}
@@ -44,7 +44,7 @@ public class EvaluatingExpressionRootNode extends XValueContainerNode<Evaluating
public static class EvaluatingResultContainer extends XValueContainer implements XDebuggerTreeListener {
private final XDebuggerEvaluationDialog myDialog;
private XDebuggerTree myTree;
private final XDebuggerTree myTree;
public EvaluatingResultContainer(final XDebuggerEvaluationDialog dialog, XDebuggerTree tree) {
myDialog = dialog;
@@ -17,12 +17,15 @@ package com.siyeh.ipp.exceptions;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ipp.base.Intention;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
import static com.intellij.psi.PsiAnnotation.TargetType;
import java.util.List;
import static com.intellij.util.ObjectUtils.assertNotNull;
public class SplitMultiCatchIntention extends Intention {
@@ -52,27 +55,30 @@ public class SplitMultiCatchIntention extends Intention {
return;
}
final PsiModifierList modifierList = parameter.getModifierList();
if (modifierList != null) {
for (PsiAnnotation annotation : modifierList.getAnnotations()) {
if (PsiImplUtil.findApplicableTarget(annotation, TargetType.TYPE_USE) == TargetType.TYPE_USE) {
annotation.delete();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
final List<PsiTypeElement> disjunctions = PsiTreeUtil.getChildrenOfTypeAsList(parameter.getTypeElement(), PsiTypeElement.class);
for (int i = 0; i < disjunctions.size(); i++) {
final PsiCatchSection copy = (PsiCatchSection)catchSection.copy();
final PsiTypeElement typeElement = assertNotNull(assertNotNull(copy.getParameter()).getTypeElement());
final PsiTypeElement newTypeElement = factory.createTypeElementFromText(disjunctions.get(i).getText(), catchSection);
typeElement.replace(newTypeElement);
grandParent.addBefore(copy, catchSection);
if (i == 0) {
// clear the original from type annotations: they belong to the first disjunction and should not appear in others
final PsiModifierList modifierList = parameter.getModifierList();
if (modifierList != null) {
for (PsiAnnotation annotation : modifierList.getAnnotations()) {
if (PsiImplUtil.findApplicableTarget(annotation, PsiAnnotation.TargetType.TYPE_USE) == PsiAnnotation.TargetType.TYPE_USE) {
annotation.delete();
}
}
}
}
}
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
for (PsiType disjunction : ((PsiDisjunctionType)type).getDisjunctions()) {
final PsiCatchSection copy = (PsiCatchSection)catchSection.copy();
final PsiParameter copyParameter = copy.getParameter();
assert copyParameter != null : copy.getText();
final PsiTypeElement typeElement = copyParameter.getTypeElement();
assert typeElement != null : copyParameter.getText();
final PsiTypeElement newTypeElement = factory.createTypeElement(disjunction);
typeElement.replace(newTypeElement);
grandParent.addBefore(copy, catchSection);
}
catchSection.delete();
}
}
@@ -168,9 +168,12 @@ public class GroovyAnnotator extends GroovyElementVisitor {
@Override
public void visitNamedArgument(GrNamedArgument argument) {
final PsiElement parent = argument.getParent().getParent();
if (parent instanceof GrIndexProperty) {
myHolder.createErrorAnnotation(argument, GroovyBundle.message("named.arguments.are.not.allowed.inside.index.operations"));
PsiElement parent = argument.getParent();
if (parent instanceof GrArgumentList) {
final PsiElement pparent = parent.getParent();
if (pparent instanceof GrIndexProperty) {
myHolder.createErrorAnnotation(argument, GroovyBundle.message("named.arguments.are.not.allowed.inside.index.operations"));
}
}
}
@@ -68545,6 +68545,7 @@ funding
fundraiser
fundraisers
funds
fundraising
funeral
funeral's
funerals
@@ -325,7 +325,11 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
final CachedValue<XmlAttributeDescriptor> value = CachedValuesManager.getManager(includedDocument.getProject()).createCachedValue(
new CachedValueProvider<XmlAttributeDescriptor>(){
public Result<XmlAttributeDescriptor> compute() {
return new Result<XmlAttributeDescriptor>(attributeDescriptor, attributeDescriptor.getDependences());
Object[] deps = attributeDescriptor.getDependences();
if (deps.length == 0) {
LOG.error(attributeDescriptor + " returned no dependencies");
}
return new Result<XmlAttributeDescriptor>(attributeDescriptor, deps);
}
},
false