Merge remote-tracking branch 'origin/master'

This commit is contained in:
Konstantin Bulenkov
2015-02-02 14:54:44 +01:00
452 changed files with 37464 additions and 4362 deletions
+5 -2
View File
@@ -218,6 +218,10 @@
<option name="TAB_SIZE" value="8" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
</codeStyleSettings>
<codeStyleSettings language="JSP">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
@@ -308,5 +312,4 @@
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</component>
</project>
</project>
+3 -1
View File
@@ -3,7 +3,9 @@
<extensionPoint name="regExpLanguageHost" beanClass="com.intellij.openapi.util.ClassExtensionPoint">
<with attribute="implementationClass" implements="org.intellij.lang.regexp.RegExpLanguageHost"/>
</extensionPoint>
<extensionPoint name="regExpModifierProvider" interface="org.intellij.lang.regexp.RegExpModifierProvider"/>
<extensionPoint name="regExpModifierProvider" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="org.intellij.lang.regexp.RegExpModifierProvider"/>
</extensionPoint>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<lang.documentationProvider language="RegExp" implementationClass="org.intellij.lang.regexp.RegExpDocumentationProvider"/>
@@ -15,7 +15,7 @@
*/
package org.intellij.lang.regexp;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.lang.LanguageExtension;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.intellij.lang.annotations.MagicConstant;
@@ -28,7 +28,7 @@ import java.util.regex.Pattern;
* @author Anna Bulenkova
*/
public interface RegExpModifierProvider {
ExtensionPointName<RegExpModifierProvider> EP = new ExtensionPointName<RegExpModifierProvider>("com.intellij.regExpModifierProvider");
LanguageExtension<RegExpModifierProvider> EP = new LanguageExtension<RegExpModifierProvider>("com.intellij.regExpModifierProvider");
@MagicConstant(flagsFromClass = Pattern.class)
int getFlags(PsiElement elementInHost, PsiFile regexp);
@@ -40,6 +40,7 @@ import com.intellij.util.ui.UIUtil;
import org.intellij.lang.regexp.RegExpLanguage;
import org.intellij.lang.regexp.RegExpModifierProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import javax.swing.border.CompoundBorder;
@@ -53,6 +54,10 @@ import java.util.regex.Pattern;
*/
public class CheckRegExpForm {
private static final String LAST_EDITED_REGEXP = "last.edited.regexp";
private static final JBColor BACKGROUND_COLOR_MATCH = new JBColor(new Color(231, 250, 219), new Color(68, 85, 66));
private static final JBColor BACKGROUND_COLOR_NOMATCH = new JBColor(new Color(255, 177, 160), new Color(110, 43, 40));
private final PsiFile myRegexpFile;
private EditorTextField mySampleText; //TODO[kb]: make it multiline
@@ -138,23 +143,33 @@ public class CheckRegExpForm {
}
private void updateBalloon() {
boolean correct = false;
PsiLanguageInjectionHost host = InjectedLanguageUtil.findInjectionHost(myRegexpFile);
boolean correct = isMatchingText(myRegexpFile, mySampleText.getText());
mySampleText.setBackground(correct ? BACKGROUND_COLOR_MATCH : BACKGROUND_COLOR_NOMATCH);
myMessage.setText(correct ? "Matches!" : "no match");
myRootPanel.revalidate();
}
@TestOnly
public static boolean isMatchingTextTest(@NotNull PsiFile regexpFile, @NotNull String sampleText) {
return isMatchingText(regexpFile, sampleText);
}
private static boolean isMatchingText(@NotNull PsiFile regexpFile, @NotNull String sampleText) {
final String regExp = regexpFile.getText();
PsiLanguageInjectionHost host = InjectedLanguageUtil.findInjectionHost(regexpFile);
int flags = 0;
if (host != null) {
for (RegExpModifierProvider provider : RegExpModifierProvider.EP.getExtensions()) {
flags = provider.getFlags(host, myRegexpFile);
for (RegExpModifierProvider provider : RegExpModifierProvider.EP.allForLanguage(host.getLanguage())) {
flags = provider.getFlags(host, regexpFile);
if (flags > 0) break;
}
}
try {
correct = Pattern.compile(myRegExp.getText(), flags).matcher(mySampleText.getText()).matches();
return Pattern.compile(regExp, flags).matcher(sampleText).matches();
} catch (Exception ignore) {}
JBColor color1 = new JBColor(new Color(231, 250, 219), new Color(68, 85, 66));
JBColor color2 = new JBColor(new Color(255, 177, 160), new Color(110, 43, 40));
mySampleText.setBackground(correct ? color1 : color2);
myMessage.setText(correct ? "Matches!" : "no match");
myRootPanel.revalidate();
return false;
}
}
+2 -2
View File
@@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/scripts" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/restApiDocGenerator/node_modules" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
@@ -35,5 +36,4 @@
<orderEntry type="module" module-name="groovy-jps-plugin" scope="RUNTIME" />
<orderEntry type="module" module-name="groovy_rt" scope="RUNTIME" />
</component>
</module>
</module>
+6
View File
@@ -1 +1,7 @@
IDS_JDK_ONLY=true
IDS_APP_TITLE=__IDE-NAME__ Launcher
IDS_VM_OPTIONS_PATH=%USERPROFILE%\\.__PRODUCT_PATHS_SELECTOR__
IDC_WINLAUNCHER=__IDE-NAME___LAUNCHER
IDS_PROPS_ENV_VAR=__IDE-NAME___PROPERTIES
IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME___VM_OPTIONS
IDS_ERROR_LAUNCHING_APP=Error launching __IDE-NAME__
+6
View File
@@ -1,2 +1,8 @@
IDS_JDK_ONLY=true
IDS_JDK_ENV_VAR=IDEA_JDK_64
IDS_APP_TITLE=__IDE-NAME__ Launcher
IDS_VM_OPTIONS_PATH=%USERPROFILE%\\.__PRODUCT_PATHS_SELECTOR__
IDC_WINLAUNCHER=__IDE-NAME___LAUNCHER
IDS_PROPS_ENV_VAR=__IDE-NAME___PROPERTIES
IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME___VM_OPTIONS
IDS_ERROR_LAUNCHING_APP=Error launching __IDE-NAME__
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>rules</key>
<dict>
<key>^bin/</key>
<true/>
<key>^lib/</key>
<true/>
<key>^license/</key>
<true/>
<key>^MacOS/</key>
<true/>
<key>^plugins/</key>
<true/>
<key>^Resources/</key>
<true/>
</dict>
</dict>
</plist>
+1
View File
@@ -0,0 +1 @@
node_modules/
+5
View File
@@ -0,0 +1,5 @@
{
"name": "IntelliJ Platform REST API",
"version": "140.2110",
"url" : "http://localhost:63342/rest"
}
+15
View File
@@ -0,0 +1,15 @@
var gulp = require('gulp')
var apidoc = require('gulp-apidoc')
var path = require('path')
var sources = path.normalize("../../platform/platform-impl/src/org/jetbrains/ide")
gulp.task('apidoc', function () {
apidoc.exec({src: sources, dest: (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + "/idea-rest-api"})
})
gulp.task('default', ['apidoc'])
gulp.task('watch', function() {
gulp.watch(sources + "/**/*.{clj,coffee,cs,dart,erl,go,java,js,php,py,rb,ts,pm}", ['apidoc'])
})
+7
View File
@@ -0,0 +1,7 @@
{
"name": "restApiDocGenerator",
"devDependencies": {
"gulp": "^3.8.10",
"gulp-apidoc": "^0.1.2"
}
}
+2 -1
View File
@@ -854,7 +854,8 @@ binding.setVariable("buildWinLauncher", { String ch, String inputPath, String ou
if (pathsSelector != null) {
def paths = getProperty("paths")
def launcherPropertiesTemp = "${paths.sandbox}/launcher.properties"
copyAndPatchFile(launcherProperties, launcherPropertiesTemp, ["PRODUCT_PATHS_SELECTOR": pathsSelector])
copyAndPatchFile(launcherProperties, launcherPropertiesTemp, ["PRODUCT_PATHS_SELECTOR": pathsSelector,
"IDE-NAME": p("component.names.product").toUpperCase()])
launcherProperties = launcherPropertiesTemp
}
@@ -15,8 +15,8 @@
*/
package com.intellij.compiler;
import com.intellij.internal.statistic.AbstractApplicationUsagesCollector;
import com.intellij.internal.statistic.CollectUsagesException;
import com.intellij.internal.statistic.UsagesCollector;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.project.Project;
@@ -30,12 +30,12 @@ import java.util.Set;
* @author Eugene Zhuravlev
* Date: 4/11/13
*/
public class CompilerSettingsUsageCollector extends UsagesCollector{
public class CompilerSettingsUsageCollector extends AbstractApplicationUsagesCollector{
public static final String GROUP_ID = "compiler";
@NotNull
@Override
public Set<UsageDescriptor> getUsages(@Nullable Project project) throws CollectUsagesException {
public Set<UsageDescriptor> getProjectUsages(@Nullable Project project) throws CollectUsagesException {
final CompilerWorkspaceConfiguration wsConfig = CompilerWorkspaceConfiguration.getInstance(project);
final Set<UsageDescriptor> result = new HashSet<UsageDescriptor>();
@@ -18,10 +18,10 @@ package com.intellij.compiler.impl;
import com.intellij.compiler.ProblemsView;
import com.intellij.icons.AllIcons;
import com.intellij.ide.errorTreeView.ErrorTreeElement;
import com.intellij.ide.errorTreeView.ErrorTreeElementKind;
import com.intellij.ide.errorTreeView.ErrorViewStructure;
import com.intellij.ide.errorTreeView.GroupingElement;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.PooledThreadExecutor;
import javax.swing.*;
import java.util.EnumSet;
import java.util.UUID;
/**
@@ -48,7 +49,8 @@ import java.util.UUID;
*/
public class ProblemsViewImpl extends ProblemsView{
private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
private static final EnumSet<ErrorTreeElementKind> ALL_MESSAGE_KINDS = EnumSet.allOf(ErrorTreeElementKind.class);
private final ProblemsViewPanel myPanel;
private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
private final Icon myActiveIcon = AllIcons.Toolwindows.Problems;
@@ -70,7 +72,6 @@ public class ProblemsViewImpl extends ProblemsView{
return;
}
final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project, true);
updateIcon(false);
final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false);
// todo: setup content?
tw.getContentManager().addContent(content);
@@ -80,6 +81,7 @@ public class ProblemsViewImpl extends ProblemsView{
tw.getContentManager().removeAllContents(true);
}
});
updateIcon();
}
});
}
@@ -89,19 +91,16 @@ public class ProblemsViewImpl extends ProblemsView{
myViewUpdater.execute(new Runnable() {
@Override
public void run() {
updateIcon(!cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId));
cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId);
updateIcon();
myPanel.reload();
}
});
}
private boolean cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
final ErrorViewStructure structure = myPanel.getErrorViewStructure();
ErrorTreeElement[] elements = structure.getChildElements(fromElement);
if (elements.length ==0) return true;
boolean result = false;
for (ErrorTreeElement element : elements) {
for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
if (element instanceof GroupingElement) {
if (scope != null) {
final VirtualFile file = ((GroupingElement)element).getFile();
@@ -111,20 +110,17 @@ public class ProblemsViewImpl extends ProblemsView{
}
if (!currentSessionId.equals(element.getData())) {
structure.removeElement(element);
result = true;
}
else {
result |= cleanupChildrenRecursively(element, scope, currentSessionId);
cleanupChildrenRecursively(element, scope, currentSessionId);
}
}
else {
if (!currentSessionId.equals(element.getData())) {
structure.removeElement(element);
result = true;
}
}
}
return result;
}
@Override
@@ -139,7 +135,7 @@ public class ProblemsViewImpl extends ProblemsView{
public void run() {
final ErrorViewStructure structure = myPanel.getErrorViewStructure();
final GroupingElement group = structure.lookupGroupingElement(groupName);
if (group != null && !sessionId.equals(group.getData())) {
if (group != null && sessionId != null && !sessionId.equals(group.getData())) {
structure.removeElement(group);
}
if (navigatable != null) {
@@ -148,21 +144,24 @@ public class ProblemsViewImpl extends ProblemsView{
else {
myPanel.addMessage(type, text, null, -1, -1, sessionId);
}
updateIcon(true);
updateIcon();
}
});
}
private void updateIcon(final boolean active) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
private void updateIcon() {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
if (tw != null) {
tw.setIcon(active ? myActiveIcon : myPassiveIcon);
if (!myProject.isDisposed()) {
final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(PROBLEMS_TOOLWINDOW_ID);
if (tw != null) {
final boolean active = myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS);
tw.setIcon(active ? myActiveIcon : myPassiveIcon);
}
}
}
}, myProject.getDisposed());
});
}
@Override
@@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project;
public class ProblemsViewPanel extends NewErrorTreeViewPanel {
public ProblemsViewPanel(Project project) {
super(project, null, false, true, null);
super(project, "reference.problems.tool.window", false, true, null);
myTree.getEmptyText().setText("No compilation problems found");
}
@@ -171,7 +171,7 @@ public class ProjectFromSourcesBuilderImpl extends ProjectImportBuilder implemen
setBaseProjectPath(path);
}
public List<Module> commit(final Project project, final ModifiableModuleModel model, final ModulesProvider modulesProvider) {
public List<Module> commit(@NotNull final Project project, final ModifiableModuleModel model, final ModulesProvider modulesProvider) {
final boolean fromProjectStructure = model != null;
ModifiableModelsProvider modelsProvider = new IdeaModifiableModelsProvider();
final LibraryTable.ModifiableModel projectLibraryTable = modelsProvider.getLibraryTableModifiableModel(project);
@@ -46,7 +46,9 @@ public abstract class LanguageLevelConfigurable implements UnnamedConfigurable {
});
myLanguageLevelCombo.insertItemAt(LanguageLevelCombo.USE_PROJECT_LANGUAGE_LEVEL, 0);
myPanel.add(new JLabel(ProjectBundle.message("module.module.language.level")),
JLabel label = new JLabel(ProjectBundle.message("module.module.language.level"));
label.setLabelFor(myLanguageLevelCombo);
myPanel.add(label,
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(12, 6, 12, 0), 0, 0));
myPanel.add(myLanguageLevelCombo,
new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(6, 6, 12, 0), 0, 0));
@@ -56,7 +56,7 @@ public abstract class ProjectImportBuilder<T> extends ProjectBuilder {
public abstract void setOpenProjectSettingsAfter(boolean on);
@Override
public List<Module> commit(Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) {
public List<Module> commit(@NotNull Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) {
return commit(project, model, modulesProvider, null);
}
@@ -52,7 +52,7 @@ public class SuppressParameterFix extends AbstractBatchSuppressByNoInspectionCom
@Override
public PsiElement getContainer(PsiElement context) {
PsiParameter psiParameter = PsiTreeUtil.getParentOfType(context, PsiParameter.class, false);
return psiParameter != null && JavaSuppressionUtil.canHave15Suppressions(psiParameter) ? psiParameter : null;
return psiParameter != null && psiParameter.getTypeElement() != null && JavaSuppressionUtil.canHave15Suppressions(psiParameter) ? psiParameter : null;
}
@Override
@@ -1448,6 +1448,24 @@ public class HighlightUtil extends HighlightUtilBase {
return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr);
}
if (qualifier != null && aClass.isInterface() && languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
//15.12.1 for method invocation expressions; 15.13 for method references
//If TypeName denotes an interface, I, then let T be the type declaration immediately enclosing the method reference expression.
//It is a compile-time error if I is not a direct superinterface of T,
//or if there exists some other direct superclass or direct superinterface of T, J, such that J is a subtype of I.
final PsiClass classT = PsiTreeUtil.getParentOfType(expr, PsiClass.class);
if (classT != null) {
for (PsiClass superClass : classT.getSupers()) {
if (superClass.isInterface() && //check spec-javac relations
superClass.isInheritor(aClass, true)) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(qualifier)
.descriptionAndTooltip(JavaErrorMessages.message("bad.qualifier.in.super.method.reference", format(aClass), formatClass(superClass))).create();
}
}
}
}
if (expr instanceof PsiThisExpression) {
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(expr, PsiMethod.class);
if (psiMethod == null || psiMethod.getContainingClass() != aClass && !isInsideDefaultMethod(psiMethod, aClass)) {
@@ -27,6 +27,8 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JdkVersionUtil;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.PsiFile;
@@ -96,6 +98,7 @@ public class IncreaseLanguageLevelFix implements IntentionAction {
}
else {
LanguageLevelProjectExtension.getInstance(project).setLanguageLevel(myLevel);
ProjectRootManagerEx.getInstanceEx(project).makeRootsChange(EmptyRunnable.INSTANCE, false, true);
}
}
@@ -94,12 +94,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final PsiElement lambdaContext = parent != null ? parent.getParent() : null;
if (lambdaContext != null &&
(LambdaUtil.isValidLambdaContext(lambdaContext) || !(lambdaContext instanceof PsiExpressionStatement)) &&
canBeConvertedToLambda(aClass, new Condition<PsiClassType>() {
@Override
public boolean value(PsiClassType type) {
return LambdaHighlightingUtil.checkInterfaceFunctional(type) == null;
}
})) {
canBeConvertedToLambda(aClass, false)) {
final PsiElement lBrace = aClass.getLBrace();
LOG.assertTrue(lBrace != null);
final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent());
@@ -194,15 +189,18 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
return null;
}
public static boolean canBeConvertedToLambda(PsiAnonymousClass aClass, Condition<PsiClassType> baseClassTypeCondition) {
if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8) && baseClassTypeCondition.value(aClass.getBaseClassType())) {
final PsiMethod[] methods = aClass.getMethods();
if (methods.length == 1 && aClass.getFields().length == 0) {
final PsiMethod method = methods[0];
return method.getBody() != null &&
!hasForbiddenRefsInsideBody(method, aClass) &&
!hasRuntimeAnnotations(method) &&
!method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
public static boolean canBeConvertedToLambda(PsiAnonymousClass aClass, boolean acceptParameterizedFunctionTypes) {
if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(aClass.getBaseClassType());
if (interfaceMethod != null && (acceptParameterizedFunctionTypes || !interfaceMethod.hasTypeParameters())) {
final PsiMethod[] methods = aClass.getMethods();
if (methods.length == 1 && aClass.getFields().length == 0) {
final PsiMethod method = methods[0];
return method.getBody() != null &&
!hasForbiddenRefsInsideBody(method, aClass) &&
!hasRuntimeAnnotations(method) &&
!method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
}
}
}
return false;
@@ -21,10 +21,8 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.RedundantCastUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -67,12 +65,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI
@Override
public void visitAnonymousClass(PsiAnonymousClass aClass) {
super.visitAnonymousClass(aClass);
if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, new Condition<PsiClassType>() {
@Override
public boolean value(PsiClassType type) {
return LambdaUtil.isFunctionalType(type);
}
})) {
if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, true)) {
final PsiMethod method = aClass.getMethods()[0];
final PsiCodeBlock body = method.getBody();
final PsiCallExpression callExpression =
@@ -216,7 +216,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
) {
DfaValue arrayVar = myFactory.createValue(((PsiArrayAccessExpression)lExpr).getArrayExpression());
if (arrayVar instanceof DfaVariableValue) {
addInstruction(new FlushVariableInstruction((DfaVariableValue)arrayVar));
addInstruction(new FlushVariableInstruction((DfaVariableValue)arrayVar, true));
}
}
}
@@ -690,6 +690,21 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
finishElement(switchStmt);
}
@Override
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
startElement(expression);
PsiExpression qualifier = expression.getQualifierExpression();
if (qualifier != null) {
qualifier.accept(this);
addInstruction(new FieldReferenceInstruction(qualifier, "Method reference qualifier"));
}
addInstruction(new PushInstruction(myFactory.createTypeValue(expression.getFunctionalInterfaceType(), Nullness.NOT_NULL), expression));
finishElement(expression);
}
@Override public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
startElement(statement);
@@ -123,7 +123,14 @@ public abstract class InstructionVisitor {
public DfaInstructionState[] visitFlushVariable(FlushVariableInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
final DfaVariableValue variable = instruction.getVariable();
if (variable != null) {
memState.flushVariable(variable);
if (instruction.isDependentsOnly()) {
for (DfaVariableValue qualified : runner.getFactory().getVarFactory().getAllQualifiedBy(variable)) {
memState.flushVariable(qualified);
}
}
else {
memState.flushVariable(variable);
}
} else {
memState.flushFields();
}
@@ -29,9 +29,19 @@ import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
public class FlushVariableInstruction extends Instruction {
private final DfaVariableValue myVariable;
private final boolean myDependentsOnly;
public FlushVariableInstruction(DfaVariableValue expr) {
myVariable = expr;
this(expr, false);
}
public FlushVariableInstruction(DfaVariableValue variable, boolean dependentsOnly) {
myVariable = variable;
myDependentsOnly = dependentsOnly;
}
public boolean isDependentsOnly() {
return myDependentsOnly;
}
public DfaVariableValue getVariable() {
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpressionList;
import com.intellij.psi.PsiFile;
@@ -30,14 +29,12 @@ import org.intellij.lang.regexp.RegExpModifierProvider;
public class JavaRegExpModifierProvider implements RegExpModifierProvider {
@Override
public int getFlags(PsiElement elementInHost, PsiFile regexp) {
if (elementInHost.getLanguage() == JavaLanguage.INSTANCE) {
final PsiExpressionList list = PsiTreeUtil.getParentOfType(elementInHost, PsiExpressionList.class);
if (list != null && list.getExpressions().length == 2 && list.getExpressionTypes()[1] == PsiType.INT) {
final Object result = JavaConstantExpressionEvaluator.computeConstantExpression(list.getExpressions()[1], false);
if (result instanceof Integer) {
//noinspection MagicConstant
return ((Integer)result).intValue();
}
final PsiExpressionList list = PsiTreeUtil.getParentOfType(elementInHost, PsiExpressionList.class);
if (list != null && list.getExpressions().length == 2 && list.getExpressionTypes()[1] == PsiType.INT) {
final Object result = JavaConstantExpressionEvaluator.computeConstantExpression(list.getExpressions()[1], false);
if (result instanceof Integer) {
//noinspection MagicConstant
return ((Integer)result).intValue();
}
}
return 0;
@@ -16,7 +16,7 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.module.LanguageLevelUtil;
import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -70,7 +70,7 @@ public class JavaLanguageLevelPusher implements FilePropertyPusher<LanguageLevel
@Override
public LanguageLevel getImmediateValue(@NotNull Module module) {
return LanguageLevelUtil.getEffectiveLanguageLevel(module);
return EffectiveLanguageLevelUtil.getEffectiveLanguageLevel(module);
}
@Override
@@ -47,6 +47,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
import com.intellij.psi.controlFlow.ControlFlowUtil;
@@ -636,7 +637,7 @@ public class ExtractMethodProcessor implements MatchProvider {
prepareMethodBody(emptyMethod, false);
final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
final PsiClass nullableAnnotationClass = JavaPsiFacade.getInstance(myProject)
.findClass(manager.getDefaultNullable(), GlobalSearchScope.allScope(myProject));
.findClass(manager.getDefaultNullable(), myElements[0].getResolveScope());
if (nullableAnnotationClass != null) {
if (myNotNullConditionalCheck || myNullConditionalCheck) {
return Nullness.NULLABLE;
@@ -670,6 +671,10 @@ public class ExtractMethodProcessor implements MatchProvider {
final List<String> getters = new ArrayList<String>(ContainerUtil.map(initialMethodNames, new Function<String, String>() {
@Override
public String fun(String propertyName) {
if (!PsiNameHelper.getInstance(myProject).isIdentifier(propertyName)) {
LOG.info(propertyName + "; " + myExpression);
return null;
}
return GenerateMembersUtil.suggestGetterName(propertyName, myReturnType, myProject);
}
}));
@@ -297,7 +297,7 @@ public class GenericsUtil {
}
else if (substituted instanceof PsiCapturedWildcardType) {
final PsiType extendsBound = ((PsiCapturedWildcardType)substituted).getUpperBound();
if (acceptExtendsBound(extendsType, extendsBound)) {
if (acceptExtendsBound(extendsType, extendsBound) || extendsType.equals(substitutor.substitute(extendsBound))) {
return null;
}
}
@@ -31,4 +31,19 @@ public interface PsiFunctionalExpression extends PsiExpression, Iconable, Naviga
* @return true if assignment SAM s = expr is correctly shaped
*/
boolean isAcceptable(PsiType left);
/**
* Potentially compatible check takes into account the presence and "shape" of functional interface target types.
*
* JLS placement:
* 15.12.2.1 Identify Potentially Applicable Methods
* A member method is potentially applicable to a method invocation if and only if all of the following are true:
* The name of the member is identical to the name of the method in the method invocation.
* The member is accessible (§6.6) to the class or interface in which the method invocation appears.
* If the member is a fixed arity method with arity n, the arity of the method invocation is equal to n,
* and for all i (1 ≤ i ≤ n), the i'th argument of the method invocation is potentially compatible, as defined below,
* with the type of the i'th parameter of the method.
* If the member is a variable arity method with arity n, etc
*/
boolean isPotentiallyCompatible(PsiType left);
}
@@ -46,4 +46,12 @@ public interface PsiLambdaExpression extends PsiFunctionalExpression {
* @return true when lambda declares parameter types explicitly
*/
boolean hasFormalParameterTypes();
/**
* A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
* The arity of the target type's function type is the same as the arity of the lambda expression.
* If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
* If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
*/
boolean isPotentiallyCompatible(PsiType left);
}
@@ -175,10 +175,7 @@ public class PsiMethodReferenceUtil {
if (resolve instanceof PsiClass) {
containingClass = (PsiClass)resolve;
substitutor = resolveResult.getSubstitutor();
final boolean isRawSubst = !methodReferenceExpression.isConstructor() &&
PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true) &&
PsiUtil.isRawSubstitutor(containingClass, substitutor);
return new QualifierResolveResult(containingClass, isRawSubst ? PsiSubstitutor.EMPTY : substitutor, true);
return new QualifierResolveResult(containingClass, substitutor, true);
}
}
}
@@ -52,11 +52,16 @@ public class FunctionalInterfaceParameterizationUtil {
@Nullable
public static PsiType getGroundTargetType(@Nullable PsiType psiClassType, @Nullable PsiLambdaExpression expr) {
return getGroundTargetType(psiClassType, expr, true);
}
@Nullable
public static PsiType getGroundTargetType(@Nullable PsiType psiClassType, @Nullable PsiLambdaExpression expr, boolean performFinalCheck) {
if (!isWildcardParameterized(psiClassType)) {
return psiClassType;
}
if (expr != null && expr.hasFormalParameterTypes()) return getFunctionalTypeExplicit(psiClassType, expr);
if (expr != null && expr.hasFormalParameterTypes()) return getFunctionalTypeExplicit(psiClassType, expr, performFinalCheck);
return psiClassType instanceof PsiClassType ? getNonWildcardParameterization((PsiClassType)psiClassType) : null;
}
@@ -64,11 +69,11 @@ public class FunctionalInterfaceParameterizationUtil {
/**
* 18.5.3. Functional Interface Parameterization Inference
*/
private static PsiType getFunctionalTypeExplicit(PsiType psiClassType, PsiLambdaExpression expr) {
private static PsiType getFunctionalTypeExplicit(PsiType psiClassType, PsiLambdaExpression expr, boolean performFinalCheck) {
final PsiParameter[] lambdaParams = expr.getParameterList().getParameters();
if (psiClassType instanceof PsiIntersectionType) {
for (PsiType psiType : ((PsiIntersectionType)psiClassType).getConjuncts()) {
final PsiType functionalType = getFunctionalTypeExplicit(psiType, expr);
final PsiType functionalType = getFunctionalTypeExplicit(psiType, expr, performFinalCheck);
if (functionalType != null) return functionalType;
}
return null;
@@ -120,12 +125,12 @@ public class FunctionalInterfaceParameterizationUtil {
//If F<A'1, ..., A'm> is not a well-formed type (that is, the type arguments are not within their bounds),
// or if F<A'1, ..., A'm> is not a subtype of F<A1, ..., Am>, no valid parameterization exists.
if (!isWellFormed(psiClass, typeParameters, newTypeParameters)) {
if (!isWellFormed(psiClass, typeParameters, newTypeParameters) || performFinalCheck && !psiClassType.isAssignableFrom(parameterization)) {
return null;
}
//Otherwise, the inferred parameterization is either F<A'1, ..., A'm>, if all the type arguments are types,
if (!TypeConversionUtil.containsWildcards(parameterization) && psiClassType.isAssignableFrom(parameterization)) {
if (!TypeConversionUtil.containsWildcards(parameterization)) {
return parameterization;
}
@@ -1130,11 +1130,11 @@ public class InferenceSession {
final PsiType pType = signature.getParameterTypes()[0];
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
// 15.28.1 If the ReferenceType is a raw type, and there exists a parameterization of this type, T, that is a supertype of P1,
// 15.13.1 If the ReferenceType is a raw type, and there exists a parameterization of this type, T, that is a supertype of P1,
// the type to search is the result of capture conversion (5.1.10) applied to T;
// otherwise, the type to search is the same as the type of the first search. Again, the type arguments, if any, are given by the method reference.
if (PsiUtil.isRawSubstitutor(containingClass, qualifierResolveResult.getSubstitutor())) {
final PsiClassType.ClassResolveResult pResult = PsiUtil.resolveGenericsClassInType(pType);
if (PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor)) {
final PsiClassType.ClassResolveResult pResult = PsiUtil.resolveGenericsClassInType(PsiUtil.captureToplevelWildcards(pType, myContext));
final PsiClass pClass = pResult.getElement();
final PsiSubstitutor receiverSubstitutor = pClass != null ? TypeConversionUtil
.getClassSubstitutor(containingClass, pClass, pResult.getSubstitutor()) : null;
@@ -1267,7 +1267,7 @@ public class InferenceSession {
final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)arg);
if (LambdaUtil.isFunctionalType(sReturnType) && LambdaUtil.isFunctionalType(tReturnType) &&
if (LambdaUtil.isFunctionalType(sReturnType) && LambdaUtil.isFunctionalType(tReturnType) &&
!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(sReturnType), TypeConversionUtil.erasure(tReturnType)) &&
!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(tReturnType), TypeConversionUtil.erasure(sReturnType))) {
@@ -1293,6 +1293,9 @@ public class InferenceSession {
}
}
}
else if (sPrimitive) {
return false;
}
}
return true;
}
@@ -1308,11 +1311,17 @@ public class InferenceSession {
if (arg instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression)arg).isExact()) {
final PsiParameter[] sParameters = sInterfaceMethod.getParameterList().getParameters();
final PsiParameter[] tParameters = tInterfaceMethod.getParameterList().getParameters();
if (session != null) {
LOG.assertTrue(sParameters.length == tParameters.length);
for (int i = 0; i < tParameters.length; i++) {
session.addConstraint(new TypeEqualityConstraint(tSubstitutor.substitute(tParameters[i].getType()),
sSubstitutor.substitute(sParameters[i].getType())));
LOG.assertTrue(sParameters.length == tParameters.length);
for (int i = 0; i < tParameters.length; i++) {
final PsiType tSubstituted = tSubstitutor.substitute(tParameters[i].getType());
final PsiType sSubstituted = sSubstitutor.substitute(sParameters[i].getType());
if (session != null) {
session.addConstraint(new TypeEqualityConstraint(tSubstituted, sSubstituted));
}
else {
if (!Comparing.equal(tSubstituted, sSubstituted)) {
return false;
}
}
}
final PsiType sReturnType = sSubstitutor.substitute(sInterfaceMethod.getReturnType());
@@ -1412,8 +1421,7 @@ public class InferenceSession {
}
public PsiType substituteWithInferenceVariables(PsiType type) {
final PsiType substituted = myInferenceSubstitution.substitute(type);
return isProperType(substituted) ? type : substituted;
return myInferenceSubstitution.substitute(type);
}
public InferenceSession findNestedCallSession(PsiExpression arg) {
@@ -50,7 +50,7 @@ public abstract class InputOutputConstraintFormula implements ConstraintFormula
if (LambdaUtil.isFunctionalType(type)) {
final PsiType functionType =
psiExpression instanceof PsiLambdaExpression
? FunctionalInterfaceParameterizationUtil.getGroundTargetType(type, (PsiLambdaExpression)psiExpression)
? FunctionalInterfaceParameterizationUtil.getGroundTargetType(type, (PsiLambdaExpression)psiExpression, false)
: type;
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
@@ -26,7 +26,7 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
return false;
}
final PsiType groundTargetType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(myT, myExpression);
final PsiType groundTargetType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(myT, myExpression, false);
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(groundTargetType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod == null) {
@@ -56,11 +56,11 @@ public class LambdaExpressionCompatibilityConstraint implements ConstraintFormul
if (returnType != null) {
final List<PsiExpression> returnExpressions = LambdaUtil.getReturnExpressions(myExpression);
if (returnType.equals(PsiType.VOID)) {
if (!returnExpressions.isEmpty() && !(myExpression.getBody() instanceof PsiExpression)) {
if (!myExpression.isVoidCompatible()) {
return false;
}
} else {
if (returnExpressions.isEmpty() && !myExpression.isValueCompatible()) { //not value-compatible
if (!myExpression.isValueCompatible()) {
return false;
}
InferenceSession callsession = session.findNestedCallSession(myExpression);
@@ -63,16 +63,10 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
if (!myExpression.isExact()) {
for (PsiParameter parameter : targetParameters) {
if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
return false;
}
}
} else {
if (myExpression.isExact()) {
final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember();
LOG.assertTrue(applicableMember != null);
final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass();
final PsiClass containingClass = qualifierResolveResult.getContainingClass();
@@ -90,7 +84,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
final PsiParameter[] parameters = applicableMember instanceof PsiMethod ? ((PsiMethod)applicableMember).getParameterList().getParameters() : PsiParameter.EMPTY_ARRAY;
if (targetParameters.length == parameters.length + 1) {
specialCase(session, constraints, substitutor, targetParameters, true);
final PsiType qualifierType = PsiMethodReferenceUtil.getQualifierType(myExpression);
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
if (qualifierClass != null) {
session.initBounds(myExpression, qualifierClass.getTypeParameters());
final PsiType pType = substitutor.substitute(targetParameters[0].getType());
constraints.add(new StrictSubtypingConstraint(session.substituteWithInferenceVariables(qualifierType), pType));
}
for (int i = 1; i < targetParameters.length; i++) {
constraints.add(new TypeCompatibilityConstraint(session.substituteWithInferenceVariables(psiSubstitutor.substitute(parameters[i - 1].getType())),
substitutor.substitute(targetParameters[i].getType())));
@@ -123,6 +123,14 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
return true;
}
//------ non exact method references --------------------
for (PsiParameter parameter : targetParameters) {
if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
return false;
}
}
final Map<PsiElement, PsiType> map = LambdaUtil.getFunctionalTypeMap();
final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType));
final JavaResolveResult resolve;
@@ -148,14 +156,28 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
final PsiType referencedMethodReturnType;
final PsiClass containingClass = method.getContainingClass();
LOG.assertTrue(containingClass != null, method);
PsiClass qContainingClass = qualifierResolveResult.getContainingClass();
final PsiClass qContainingClass = qualifierResolveResult.getContainingClass();
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
if (qContainingClass != null) {
// 15.13.1 If the ReferenceType is a raw type, and there exists a parameterization of this type, T, that is a supertype of P1,
// the type to search is the result of capture conversion (5.1.10) applied to T;
// otherwise, the type to search is the same as the type of the first search. Again, the type arguments, if any, are given by the method reference.
if ( PsiUtil.isRawSubstitutor(qContainingClass, psiSubstitutor)) {
psiSubstitutor = PsiSubstitutor.EMPTY;
if (targetParameters.length == method.getParameterList().getParametersCount() + 1) {
final PsiType pType = substitutor.substitute(targetParameters[0].getType());
PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(PsiUtil.captureToplevelWildcards(pType, myExpression));
PsiClass paramClass = resolveResult.getElement();
LOG.assertTrue(paramClass != null);
psiSubstitutor = TypeConversionUtil.getClassSubstitutor(qContainingClass, paramClass, resolveResult.getSubstitutor());
LOG.assertTrue(psiSubstitutor != null);
}
else {
psiSubstitutor = PsiSubstitutor.EMPTY;
}
}
if (qContainingClass.isInheritor(containingClass, true)) {
psiSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, PsiSubstitutor.EMPTY);
psiSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, psiSubstitutor);
LOG.assertTrue(psiSubstitutor != null);
}
}
@@ -202,52 +224,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
}
}
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (targetParameters.length == parameters.length + 1 && !method.isVarArgs() &&
PsiPolyExpressionUtil.mentionsTypeParameters(referencedMethodReturnType, ContainerUtil.newHashSet(containingClass.getTypeParameters()))) { //todo specification bug?
specialCase(session, constraints, substitutor, targetParameters, false);
}
constraints.add(new TypeCompatibilityConstraint(returnType, session.substituteWithInferenceVariables(psiSubstitutor.substitute(referencedMethodReturnType))));
constraints.add(new TypeCompatibilityConstraint(returnType,
session.substituteWithInferenceVariables(psiSubstitutor.substitute(referencedMethodReturnType))));
}
return true;
}
private void specialCase(InferenceSession session,
List<ConstraintFormula> constraints,
PsiSubstitutor substitutor,
PsiParameter[] targetParameters,
boolean ignoreRaw) {
final PsiElement qualifier = myExpression.getQualifier();
PsiType qualifierType = null;
if (qualifier instanceof PsiTypeElement) {
qualifierType = ((PsiTypeElement)qualifier).getType();
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
if (qualifierClass != null) {
qualifierType = JavaPsiFacade.getElementFactory(myExpression.getProject()).createType(qualifierClass, PsiSubstitutor.EMPTY);
}
}
else if (qualifier instanceof PsiExpression) {
qualifierType = ((PsiExpression)qualifier).getType();
if (qualifierType == null && qualifier instanceof PsiReferenceExpression) {
final JavaResolveResult resolveResult = ((PsiReferenceExpression)qualifier).advancedResolve(false);
final PsiElement res = resolveResult.getElement();
if (res instanceof PsiClass) {
PsiClass containingClass = (PsiClass)res;
final boolean isRawSubst = !ignoreRaw && !myExpression.isConstructor() && PsiUtil.isRawSubstitutor(containingClass, resolveResult.getSubstitutor());
qualifierType = JavaPsiFacade.getElementFactory(res.getProject()).createType(containingClass, isRawSubst ? PsiSubstitutor.EMPTY : resolveResult.getSubstitutor());
}
}
}
final PsiClass qualifierClass = PsiUtil.resolveClassInType(qualifierType);
if (qualifierClass != null) {
session.initBounds(myExpression, qualifierClass.getTypeParameters());
constraints.add(new StrictSubtypingConstraint(session.substituteWithInferenceVariables(qualifierType),
session.substituteWithInferenceVariables(substitutor.substitute(targetParameters[0].getType()))));
}
}
@Override
public void apply(PsiSubstitutor substitutor, boolean cache) {
myT = substitutor.substitute(myT);
@@ -100,7 +100,8 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
final PsiExpressionList argumentList = getArgumentList();
final PsiType[] typeParameters = reference.getTypeParameters();
return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext,
argumentList != null ? argumentList.getExpressionTypes() : null, typeParameters.length > 0 ? typeParameters : null,
argumentList != null ? argumentList.getExpressionTypes() : null,
method.hasTypeParameters() && typeParameters.length > 0 ? typeParameters : null,
getLanguageLevel()) {
@Override
public boolean isVarargs() {
@@ -177,9 +177,6 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
}
final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class);
leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this);
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType);
if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) {
final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList);
if (candidateProperties != null) {
@@ -194,6 +191,7 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
}
}
leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this);
if (!isPotentiallyCompatible(leftType)) {
return false;
}
@@ -202,9 +200,12 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
return true;
}
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
if (interfaceMethod == null) return false;
if (interfaceMethod.hasTypeParameters()) return false;
final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult);
if (hasFormalParameterTypes()) {
@@ -239,11 +240,8 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi
return true;
}
//A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true:
// The arity of the target type's function type is the same as the arity of the lambda expression.
// If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
// If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2).
private boolean isPotentiallyCompatible(PsiType left) {
@Override
public boolean isPotentiallyCompatible(PsiType left) {
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(left);
if (interfaceMethod == null) return false;
@@ -488,7 +488,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
methodReturnType = JavaPsiFacade.getElementFactory(getProject()).createType(containingClass, subst);
}
return TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false);
return TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType);
}
return false;
}
@@ -388,3 +388,4 @@ feature.method.references=Method references
feature.lambda.expressions=Lambda expressions
feature.type.annotations=Type annotations
insufficient.language.level={0} are not supported at this language level
bad.qualifier.in.super.method.reference=Bad type qualifier in default super call: redundant interface {0} is extended by {1}
+1
View File
@@ -33,5 +33,6 @@
<orderEntry type="module" module-name="xml-psi-impl" scope="TEST" />
<orderEntry type="module" module-name="properties-psi-api" scope="TEST" />
<orderEntry type="module" module-name="java-decompiler-plugin" scope="TEST" />
<orderEntry type="module" module-name="RegExpSupport" scope="TEST" />
</component>
</module>
@@ -0,0 +1,11 @@
interface I {
default void m() {}
}
interface J extends I {}
class C implements I, J {
{
<error descr="Bad type qualifier in default super call: redundant interface I is extended by J">I</error>.super.m();
}
}
@@ -0,0 +1,23 @@
class Main<T> {
{
I<Main<String> > aNew = Main[]::new;
I<Main<?> > aNew1 = Main<?>[]::new;
I<Main<? extends String>> aNew2 = <error descr="Generic array creation">Main<? extends String>[]</error>::new;
I<int[]> p = int[][]::new;
I<Main<String>[]> a = Main[][]::new;
I<Main<?>[]> a1 = Main<?>[][]::new;
I<Main<? extends String>[]> a2 = <error descr="Generic array creation">Main<? extends String>[][]</error>::new;
I<Inner<String>> inn1 = Main.Inner[]::new;
I<Main<?>.Inner<?>> inn2 = Main<?>.Inner<?>[]::new;
I<Main<String>.Inner<String>> inn3 = <error descr="Generic array creation">Main<String>.Inner<String>[]</error>::new;
}
class Inner<P> {}
interface I<K> {
K[] v(int i);
}
}
@@ -0,0 +1,24 @@
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;
abstract class Test {
void p(final Stream<List<Integer>> stream){
stream.flatMap(Collection::<String>stream);
stream.flatMap(Collection::<<error descr="Unexpected wildcard">? extends String</error>>stream);
stream.flatMap(Collection::<<error descr="Unexpected wildcard">?</error>>stream);
stream.flatMap(Collection::<<error descr="Unexpected wildcard">? super String</error>>stream);
}
static <T> void foo(T t) {}
interface I {
void m(String s);
}
{
I i = Test::<String>foo;
I i1 = Test::<Integer><error descr="Cannot resolve method 'foo'">foo</error>;
I i2 = Test::foo;
}
}
@@ -0,0 +1,11 @@
import java.util.concurrent.Callable;
class Test<T> {
public <P> Test() {
}
{
Callable<Test<String>> c = <error descr="Bad return type in method reference: cannot convert Test to Test<java.lang.String>">Test::<String>new</error>;
Callable<Test<String>> c1 = Test<String>::<String>new;
}
}
@@ -0,0 +1,12 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
Stream<List<? extends Main>> listStream = new ArrayList<List<? extends Main>>().stream();
Stream<? extends Main> l1 = listStream.flatMap(Collection::stream);
Stream<? extends Main> l2 = listStream.flatMap(List::stream);
}
}
@@ -0,0 +1,42 @@
interface I {
default void a() {}
}
interface J extends I {}
class A implements I {}
class B extends A {}
class C implements J {}
class Test1 implements I { { Runnable r = I.super::a; } }
class Test2 implements J { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
class Test3 implements I, J { { Runnable r = <error descr="Bad type qualifier in default super call: redundant interface I is extended by J">I</error>.super::a; } }
class Test5 extends A implements I { { Runnable r = I.super::a; } }
class Test6 extends A implements J { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
class Test7 extends B { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
class Test8 extends C { { Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a; } }
class Test {
{
class LocalJ implements I {
}
class Test3 extends LocalJ implements I {
{
Runnable r = I.super::a;
}
}
new I() {
{
Runnable r = I.super::a;
}
};
new A() {
{
Runnable r = <error descr="'I' is not an enclosing class">I.super</error>::a;
}
};
}
}
@@ -0,0 +1,29 @@
interface I1 {
int i1(int i);
}
interface I2 {
Integer i2(Integer i);
}
interface I3 {
Integer i3(int i);
}
class Test {
private void <warning descr="Private method 'm(I1)' is never used">m</warning>(I1 i1) {System.out.println(i1);}
private void <warning descr="Private method 'm(I2)' is never used">m</warning>(I2 i2) {System.out.println(i2);}
private void m1(I1 i1) {System.out.println(i1);}
private void <warning descr="Private method 'm1(I3)' is never used">m1</warning>(I3 i2) {System.out.println(i2);}
void test() {
m <error descr="Ambiguous method call: both 'Test.m(I1)' and 'Test.m(I2)' match">(this::bar)</error>;
m1(this::bar);
}
int bar(int i) {
return i;
}
}
@@ -0,0 +1,37 @@
class Test {
interface GetInt { int get(); }
interface GetInteger { Integer get(); }
private void <warning descr="Private method 'm(Test.GetInt)' is never used">m</warning>(GetInt getter) {
System.out.println(getter);
}
private void m(GetInteger getter) {
System.out.println(getter);
}
void test(boolean cond) {
m<error descr="Cannot resolve method 'm(<lambda expression>)'">(() -> {
if (cond)
return 42;
else
return foo();
})</error>;
m(() -> {
return foo();
});
m(() -> {
if (cond)
return new Integer(42);
else
return foo();
});
}
private <T> T foo() {
return null;
}
}
@@ -0,0 +1,18 @@
interface I {
void g();
}
interface J {
<<warning descr="Type parameter 'T' is never used">T</warning>> void f();
}
class Test {
void m(I i) {System.out.println(i);}
void m(J j) {System.out.println(j);}
void m2(J j){System.out.println(j);}
{
m (() -> {});
m2(<error descr="Target method is generic">() -> {}</error>);
}
}
@@ -0,0 +1,18 @@
import org.jetbrains.annotations.Nullable;
class BrokenAlignment {
{
Runnable t = <warning descr="Dereference of 'getString()' may produce 'java.lang.NullPointerException'">getString()</warning>::length;
Runnable t2 = BrokenAlignment::getStringStatic;
}
@Nullable
private String getString() {
return null;
}
@Nullable
private static String getStringStatic() {
return null;
}
}
@@ -0,0 +1,53 @@
import org.jetbrains.annotations.*;
class Test {
@NotNull
public static int[] add(@Nullable final int[] ints, final int from, final int to) {
if (ints == null || ints.length == 0)
return new int[]{from, to};
for (int i = 0, j = 1; j < ints.length; i+=2, j+=2) {
final int intStart = ints[i];
final int intFinish = ints[j];
//check contained
if (intStart <= from && to <= intFinish)
return ints;
//try expand 'to' bound
if (intStart <= from && from <= intFinish) {
ints[j] = to;
return ints;
}
//try expand 'from' bound
if (intStart <= to && to <= intFinish) {
ints[i] = from;
return ints;
}
//if we add an interval that contains ors interval
//may produce duplicates
if (from <= intStart && intFinish <= to) {
ints[i] = from;
ints[j] = to;
return ints;
}
if (from == intFinish + 1) {
ints[j] = to;
return ints;
}
if (to == intStart - 1) {
ints[i] = from;
return ints;
}
}
//TODO: insert interval sorted?
final int[] newInts = new int[ints.length + 2];
System.arraycopy(ints, 0, newInts, 0, ints.length);
newInts[ints.length] = from;
newInts[ints.length+1] = to;
return newInts;
}}
@@ -2,7 +2,7 @@ class A {
boolean foo() {
Inner inner = new Inner().invoke();
if (inner.is()) return inner.getFoo();
if (inner.is()) return inner.isFoo();
return false;
@@ -16,7 +16,7 @@ class A {
return myResult;
}
public Boolean getFoo() {
public Boolean isFoo() {
return foo;
}
@@ -0,0 +1,107 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.ArrayUtil;
import org.intellij.lang.regexp.RegExpLanguage;
import org.intellij.lang.regexp.RegExpParserDefinition;
import org.intellij.lang.regexp.intention.CheckRegExpForm;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.regex.Pattern;
public class JavaCheckRegexpWithFlagsTest extends CodeInsightTestCase {
private static String getJavaText(@NotNull String regExp, int flags) {
return "import java.util.regex.Pattern;\n" +
"\n" +
"public class Test {\n" +
" public void foo() {\n" +
" Pattern.compile(\"<caret>" + regExp + "\", " + flags + ");\n" +
" }\n" +
"}\n";
}
private void defaultTest(@NotNull String regExp, int flags, @NotNull String[] matching, @NotNull String[] nonMatching) throws Exception {
LanguageParserDefinitions.INSTANCE.addExplicitExtension(RegExpLanguage.INSTANCE,
new RegExpParserDefinition());
// the 1.8 mock jdk has the needed Pattern class
PsiTestUtil.removeAllRoots(myModule, IdeaTestUtil.getMockJdk18());
configureByText(JavaFileType.INSTANCE, getJavaText(regExp, flags));
final PsiFile regexpFile = setUpRegexpInjectionAndGetRegexpFile();
for (String text : matching) {
assertTrue("Text '" + text + "' should match", CheckRegExpForm.isMatchingTextTest(regexpFile, text));
}
for (String text : nonMatching) {
assertFalse("Text '" + text + "' should not match", CheckRegExpForm.isMatchingTextTest(regexpFile, text));
}
}
@NotNull
private PsiFile setUpRegexpInjectionAndGetRegexpFile() {
final PsiFile file = getFile();
int offsetWithRegexp = file.getText().indexOf("Pattern.compile(\"")
+ "Pattern.compile(\"".length();
final PsiElement stringLiteralLeaf = file.findElementAt(offsetWithRegexp);
assertNotNull(stringLiteralLeaf);
assertNotNull(stringLiteralLeaf.getParent());
assertTrue(stringLiteralLeaf.getParent() instanceof PsiLanguageInjectionHost);
final PsiLanguageInjectionHost elementWithInjection = ((PsiLanguageInjectionHost)stringLiteralLeaf.getParent());
InjectedLanguageUtil.enumerate(elementWithInjection, file, false, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
public void visit(@NotNull final PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
}
});
assertTrue(InjectedLanguageUtil.hasInjections(elementWithInjection));
final PsiElement elementInInjected =
InjectedLanguageUtil.findElementInInjected(elementWithInjection, offsetWithRegexp);
final PsiFile regexpFile = PsiTreeUtil.getParentOfType(elementInInjected, PsiFile.class);
assertNotNull(regexpFile);
return regexpFile;
}
public void testSimple() throws Exception {
defaultTest("abc|def|xy.", 0, new String[]{"abc", "def", "xyz"}, new String[]{"", "abcd", "Abc", "xy\n"});
}
public void testEnsureFlagsParameterIsUsed() throws Exception {
defaultTest("abc|def|xy.", Pattern.DOTALL, new String[]{"xyz", "xy\n"}, ArrayUtil.EMPTY_STRING_ARRAY);
}
public void testEnsureJavaNotRubyModeIsEnabled() throws Exception {
defaultTest("(?ms:^abc$.*)|(?m:xy.)", 0, new String[]{"abc", "abc\na", "xyz"}, new String[]{"xy\n"});
}
}
@@ -788,6 +788,10 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
doTest(false);
}
public void testSuperInterfaceMethodCalledByMatterOfInterface() throws Exception {
doTest(false);
}
private void doTest() {
doTest(false);
}
@@ -80,6 +80,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testLiftedIntersectionType() { doTest(); }
public void testInferenceFromReturnStatements() { doTest(); }
public void testDownUpThroughLambdaReturnStatements() { doTest(); }
@Bombed(year = 2015, month = Calendar.MARCH, day = 30)
public void testIDEA124547() { doTest(); }
public void testIDEA118362() { doTest(); }
public void testIDEA126056() { doTest(); }
@@ -162,6 +163,7 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
@Bombed(year = 2015, month = Calendar.MARCH, day = 30)
public void testIDEA127124() throws Exception {
doTest();
}
@@ -342,6 +342,26 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testRawReferenceTypeWithReceiver() throws Exception {
doTest();
}
public void testMethodReferenceTypeArgumentsApplicability() throws Exception {
doTest();
}
public void testTypeNameInterfaceSuperMethodReferenceApplicability() throws Exception {
doTest();
}
public void testNewParameterizedReferenceOnRawType() throws Exception {
doTest();
}
public void testArrayTypeNewReifiable() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -67,6 +67,18 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testLambdaIsNotCongruentWithFunctionalTypeWithTypeParams() throws Exception {
doTest();
}
public void testDetectPolyExpressionInReturnsOfExplicitlyTypedLambdaWhenPrimitiveCouldWin() throws Exception {
doTest();
}
public void testDetectNotEqualParametersInFunctionalTypesForExactMethodReferences() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}
@@ -76,6 +76,8 @@ public class DataFlowInspection8Test extends LightCodeInsightFixtureTestCase {
});
}
public void testMethodReferenceOnNullable() { doTest(); }
public void testNullableForeachVariable() {
setupCustomAnnotations();
doTest();
@@ -282,6 +282,8 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testNumberComparisonsWhenValueIsKnown() { doTest(); }
public void testFloatComparisons() { doTest(); }
public void testNullableArray() { doTest(); }
public void testAccessingSameArrayElements() { doTest(); }
public void testParametersAreNonnullByDefault() {
@@ -16,22 +16,26 @@
package com.intellij.ide.util.projectWizard;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.SdkTypeId;
import com.intellij.openapi.roots.CompilerModuleExtension;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -128,7 +132,7 @@ public class JavaModuleBuilder extends ModuleBuilder implements SourcePathsBuild
canonicalPath = myCompilerOutputPath;
}
compilerModuleExtension
.setCompilerOutputPath(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(canonicalPath)));
.setCompilerOutputPath(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(canonicalPath)));
}
else {
compilerModuleExtension.inheritCompilerOutputPath(true);
@@ -148,6 +152,14 @@ public class JavaModuleBuilder extends ModuleBuilder implements SourcePathsBuild
}
}
@Nullable
@Override
public List<Module> commit(@NotNull Project project, ModifiableModuleModel model, ModulesProvider modulesProvider) {
LanguageLevel defaultLevel = LanguageLevelProjectExtension.getInstance(ProjectManager.getInstance().getDefaultProject()).getLanguageLevel();
LanguageLevelProjectExtension.getInstance(project).setLanguageLevel(defaultLevel);
return super.commit(project, model, modulesProvider);
}
private static String getUrlByPath(final String path) {
return VfsUtil.getUrlForLibraryRoot(new File(path));
}
@@ -7,6 +7,7 @@ src/b.p
End of files
Cleaning output files:
out/production/m/PackageFacade.class
out/production/m/a.class
out/production/m/xxx/PackageFacade.class
out/production/m/xxx/b.class
End of files
@@ -4,6 +4,7 @@ out/production/m/b.class
End of files
Cleaning output files:
out/production/m/PackageFacade.class
out/production/m/a.class
End of files
Compiling files:
src/a.p
@@ -15,19 +15,25 @@
*/
package org.jetbrains.jps.builders;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.ObjectUtils;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntObjectHashMap;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.cmdline.ProjectDescriptor;
import org.jetbrains.jps.incremental.MessageHandler;
import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.DoneSomethingNotification;
import org.jetbrains.jps.incremental.storage.OutputToTargetRegistry;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import static org.junit.Assert.*;
@@ -53,6 +59,7 @@ public class BuildResult implements MessageHandler {
final PrintStream stream = new PrintStream(dump);
try {
pd.dataManager.getMappings().toStream(stream);
dumpSourceToOutputMappings(pd, stream);
}
finally {
stream.close();
@@ -62,6 +69,63 @@ public class BuildResult implements MessageHandler {
myMappingsDump = dump.toString();
}
private static void dumpSourceToOutputMappings(ProjectDescriptor pd, PrintStream stream) throws IOException {
List<BuildTarget<?>> targets = new ArrayList<BuildTarget<?>>(pd.getBuildTargetIndex().getAllTargets());
Collections.sort(targets, new Comparator<BuildTarget<?>>() {
@Override
public int compare(BuildTarget<?> o1, BuildTarget<?> o2) {
return StringUtil.comparePairs(o1.getTargetType().getTypeId(), o1.getId(), o2.getTargetType().getTypeId(), o2.getId(), false);
}
});
final TIntObjectHashMap<BuildTarget<?>> id2Target = new TIntObjectHashMap<BuildTarget<?>>();
for (BuildTarget<?> target : targets) {
id2Target.put(pd.dataManager.getTargetsState().getBuildTargetId(target), target);
}
TIntObjectHashMap<String> hashCodeToOutputPath = new TIntObjectHashMap<String>();
for (BuildTarget<?> target : targets) {
stream.println("Begin Of SourceToOutput (target " + getTargetIdWithTypeId(target) + ")");
SourceToOutputMapping map = pd.dataManager.getSourceToOutputMap(target);
List<String> sourcesList = new ArrayList<String>(map.getSources());
Collections.sort(sourcesList);
for (String source : sourcesList) {
List<String> outputs = new ArrayList<String>(ObjectUtils.notNull(map.getOutputs(source), Collections.<String>emptySet()));
Collections.sort(outputs);
for (String output : outputs) {
hashCodeToOutputPath.put(FileUtil.pathHashCode(output), output);
}
stream.println(" " + source + " -> " + StringUtil.join(outputs, ","));
}
stream.println("End Of SourceToOutput (target " + getTargetIdWithTypeId(target) + ")");
}
OutputToTargetRegistry registry = pd.dataManager.getOutputToTargetRegistry();
List<Integer> keys = new ArrayList<Integer>(registry.getKeys());
Collections.sort(keys);
stream.println("Begin Of OutputToTarget");
for (Integer key : keys) {
TIntHashSet targetsIds = registry.getState(key);
if (targetsIds == null) continue;
final List<String> targetsNames = new ArrayList<String>();
targetsIds.forEach(new TIntProcedure() {
@Override
public boolean execute(int value) {
BuildTarget<?> target = id2Target.get(value);
targetsNames.add(target != null ? getTargetIdWithTypeId(target) : "<unknown " + value + ">");
return true;
}
});
Collections.sort(targetsNames);
stream.println(hashCodeToOutputPath.get(key) + " -> " + targetsNames);
}
stream.println("End Of OutputToTarget");
}
@NotNull
private static String getTargetIdWithTypeId(BuildTarget<?> target) {
return target.getTargetType().getTypeId() + ":" + target.getId();
}
@Override
public void processMessage(BuildMessage msg) {
if (msg.getKind() == BuildMessage.Kind.ERROR) {
@@ -72,7 +72,8 @@ class MockPackageFacadeGenerator : ModuleLevelBuilder(BuilderCategory.SOURCE_PRO
val mappings = context.getProjectDescriptor().dataManager.getMappings()
val callback = JavaBuilderUtil.getDependenciesRegistrar(context)
fun generateClass(packageName: String, className: String, target: ModuleBuildTarget, sources: Collection<String>, generate: (ClassWriter.() -> Unit)? = null) {
fun generateClass(packageName: String, className: String, target: ModuleBuildTarget, sources: Collection<String>,
allSources: Collection<String>, generate: (ClassWriter.() -> Unit)? = null) {
val writer = ClassWriter(ClassWriter.COMPUTE_FRAMES)
val fullClassName = StringUtil.getQualifiedName(packageName, className).replace('.', '/')
writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, fullClassName, null, "java/lang/Object", null)
@@ -84,39 +85,53 @@ class MockPackageFacadeGenerator : ModuleLevelBuilder(BuilderCategory.SOURCE_PRO
val classBytes = writer.toByteArray()
FileUtil.writeToFile(outputFile, classBytes)
outputConsumer.registerOutputFile(target, outputFile, sources)
callback.associate(fullClassName.replace('/', '.'), sources, ClassReader(classBytes))
callback.associate(fullClassName.replace('/', '.'), allSources, ClassReader(classBytes))
}
for (target in chunk.getTargets()) {
val packagesStorage = context.getProjectDescriptor().dataManager.getStorage(target, PACKAGE_CACHE_STORAGE_PROVIDER)
for (file in filesToCompile[target]) {
generateClass(getPackageName(file), FileUtil.getNameWithoutExtension(file), target, listOf(file.getAbsolutePath()))
val sources = listOf(file.getAbsolutePath())
generateClass(getPackageName(file), FileUtil.getNameWithoutExtension(file), target, sources, sources)
}
val packagesToGenerate = filesToCompile[target].mapTo(THashSet<String>(), ::getPackageName)
filesToCompile[target].mapNotNullTo(packagesToGenerate) { packagesStorage.getState(it.getAbsolutePath()) }
val packagesToGenerate = LinkedHashMap<String, MutableList<File>>()
filesToCompile[target].forEach {
val currentName = getPackageName(it)
if (currentName !in packagesToGenerate) packagesToGenerate[currentName] = ArrayList()
packagesToGenerate[currentName].add(it)
val oldName = packagesStorage.getState(it.getAbsolutePath())
if (oldName != null && oldName != currentName && oldName !in packagesToGenerate) {
packagesToGenerate[oldName] = ArrayList()
}
}
val packagesFromDeletedFiles = dirtyFilesHolder.getRemovedFiles(target).filter { isCompilable(File(it)) }.mapNotNull { packagesStorage.getState(it) }
packagesToGenerate.addAll(packagesFromDeletedFiles)
packagesFromDeletedFiles.forEach {
if (it !in packagesToGenerate) {
packagesToGenerate[it] = ArrayList()
}
}
val getParentFile: (File) -> File = { it.getParentFile() }
val dirsToCheck = filesToCompile[target].mapTo(THashSet(FileUtil.FILE_HASHING_STRATEGY), getParentFile)
packagesFromDeletedFiles.flatMap { mappings.getClassSources(mappings.getName(StringUtil.getQualifiedName(it, "PackageFacade"))) }
.map(getParentFile).filterNotNullTo(dirsToCheck)
for (packageName in packagesToGenerate) {
for ((packageName, dirtyFiles) in packagesToGenerate) {
val files = dirsToCheck.map { it.listFiles() }.filterNotNull().flatMap { it.toList() }.filter { isCompilable(it) && packageName == getPackageName(it) }
if (files.isEmpty()) continue
val classNames = files.map { FileUtilRt.getNameWithoutExtension(it.getName()) }.sort()
val sources = files.map { it.getAbsolutePath() }
val dirtySource = dirtyFiles.map { it.getAbsolutePath() }
val allSources = files.map { it.getAbsolutePath() }
generateClass(packageName, "PackageFacade", target, sources) {
generateClass(packageName, "PackageFacade", target, dirtySource, allSources) {
for (fileName in classNames) {
val fieldClass = StringUtil.getQualifiedName(packageName, fileName).replace('.', '/')
visitField(Opcodes.ACC_PUBLIC, StringUtil.decapitalize(fileName), "L$fieldClass;", null, null).visitEnd()
}
}
for (source in sources) {
for (source in dirtySource) {
packagesStorage.update(FileUtil.toSystemIndependentName(source), packageName)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.codeHighlighting;
import com.intellij.icons.AllIcons;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -22,6 +23,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.JBColor;
import com.intellij.util.IconUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.ColorIcon;
@@ -38,7 +40,18 @@ public class HighlightDisplayLevel {
public static final HighlightDisplayLevel GENERIC_SERVER_ERROR_OR_WARNING = new HighlightDisplayLevel(HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING,
createIconByKey(CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING));
public static final HighlightDisplayLevel ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createIconByKey(CodeInsightColors.ERRORS_ATTRIBUTES));
public static final HighlightDisplayLevel ERROR = new HighlightDisplayLevel(HighlightSeverity.ERROR, createErrorIcon());
@NotNull
private static Icon createErrorIcon() {
return new SingleColorIcon(CodeInsightColors.ERRORS_ATTRIBUTES) {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
IconUtil.colorize(AllIcons.General.InspectionsError, getColor()).paintIcon(c, g, x, y);
}
};
}
public static final HighlightDisplayLevel WARNING = new HighlightDisplayLevel(HighlightSeverity.WARNING, createIconByKey(CodeInsightColors.WARNINGS_ATTRIBUTES));
private static final Icon DO_NOT_SHOW_KEY = createIconByKey(TextAttributesKey.createTextAttributesKey("DO_NOT_SHOW"));
public static final HighlightDisplayLevel DO_NOT_SHOW = new HighlightDisplayLevel(HighlightSeverity.INFORMATION, DO_NOT_SHOW_KEY);
@@ -99,8 +112,8 @@ public class HighlightDisplayLevel {
return mySeverity;
}
public static void registerSeverity(@NotNull HighlightSeverity severity, final TextAttributesKey key) {
Icon severityIcon = createIconByKey(key);
public static void registerSeverity(@NotNull HighlightSeverity severity, @NotNull TextAttributesKey key, @Nullable Icon icon) {
Icon severityIcon = icon != null ? icon : createIconByKey(key);
final HighlightDisplayLevel level = ourMap.get(severity);
if (level == null) {
new HighlightDisplayLevel(severity, severityIcon);
@@ -111,7 +124,7 @@ public class HighlightDisplayLevel {
}
public static int getEmptyIconDim() {
return JBUI.scale(13);
return JBUI.scale(14);
}
public static Icon createIconByKey(@NotNull TextAttributesKey key) {
@@ -141,7 +154,7 @@ public class HighlightDisplayLevel {
public static class SingleColorIcon implements Icon, ColoredIcon {
private final TextAttributesKey myKey;
public SingleColorIcon(final TextAttributesKey key) {
public SingleColorIcon(@NotNull TextAttributesKey key) {
myKey = key;
}
@@ -165,11 +178,9 @@ public class HighlightDisplayLevel {
}
@Override
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(getColor());
g.translate(x, y);
g.fillPolygon(new int[]{0, getEmptyIconDim(), getEmptyIconDim()}, new int[]{0, 0, getEmptyIconDim()}, 3);
g.translate(-x, -y);
g.fillRect(x + 2, y + 2, 10, 10);
}
@Override
@@ -0,0 +1,18 @@
package com.intellij.codeInspection;
import com.intellij.psi.PsiElement;
import com.intellij.util.ThreeState;
/**
* This kind of suppression fix allows to clients to specify whether the fix should
* be invoked on injected elements or on elements of host files.
* <p/>
* By default suppression fixes on injected elements are able to make suppression inside injection only.
* Whereas implementation of this interface will be provided for suppressing inside injection and in injection host.
* See {@link InspectionProfileEntry#getBatchSuppressActions(PsiElement)} for details.
*/
public interface InjectionAwareSuppressQuickFix extends SuppressQuickFix {
ThreeState isShouldBeAppliedToInjectionHost();
void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost);
}
@@ -17,6 +17,7 @@ package com.intellij.codeInspection;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.lang.Language;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
@@ -24,8 +25,10 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import com.intellij.util.ResourceUtil;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.SerializationFilter;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
@@ -44,14 +47,16 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @author anna
* @since 28-Nov-2005
*/
@SuppressWarnings("JavadocReference")
public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public abstract class InspectionProfileEntry implements BatchSuppressableTool {
public static final String GENERAL_GROUP_NAME = InspectionsBundle.message("inspection.general.tools.group.name");
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.InspectionProfileEntry");
@@ -93,22 +98,52 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
Set<SuppressQuickFix> fixes = new THashSet<SuppressQuickFix>(new TObjectHashingStrategy<SuppressQuickFix>() {
@Override
public int computeHashCode(SuppressQuickFix object) {
return object.getName().hashCode();
int result = object instanceof InjectionAwareSuppressQuickFix
? ((InjectionAwareSuppressQuickFix)object).isShouldBeAppliedToInjectionHost().hashCode()
: 0;
return 31 * result + object.getName().hashCode();
}
@Override
public boolean equals(SuppressQuickFix o1, SuppressQuickFix o2) {
if (o1 instanceof InjectionAwareSuppressQuickFix && o2 instanceof InjectionAwareSuppressQuickFix) {
if (((InjectionAwareSuppressQuickFix)o1).isShouldBeAppliedToInjectionHost() != ((InjectionAwareSuppressQuickFix)o2).isShouldBeAppliedToInjectionHost()) {
return false;
}
}
return o1.getName().equals(o2.getName());
}
});
Set<InspectionSuppressor> suppressors = getSuppressors(element);
final PsiLanguageInjectionHost injectionHost = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element);
if (injectionHost != null) {
Set<InspectionSuppressor> injectionHostSuppressors = getSuppressors(injectionHost);
for (InspectionSuppressor suppressor : injectionHostSuppressors) {
addAllSuppressActions(fixes, injectionHost, suppressor, ThreeState.YES, getShortName());
}
}
for (InspectionSuppressor suppressor : suppressors) {
SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
fixes.addAll(Arrays.asList(actions));
addAllSuppressActions(fixes, element, suppressor, injectionHost != null ? ThreeState.NO : ThreeState.UNSURE, getShortName());
}
return fixes.toArray(new SuppressQuickFix[fixes.size()]);
}
private static void addAllSuppressActions(Set<SuppressQuickFix> fixes,
PsiElement element,
InspectionSuppressor suppressor,
ThreeState appliedToInjectionHost,
String toolShortName) {
final SuppressQuickFix[] actions = suppressor.getSuppressActions(element, toolShortName);
for (SuppressQuickFix action : actions) {
if (action instanceof InjectionAwareSuppressQuickFix) {
((InjectionAwareSuppressQuickFix)action).setShouldBeAppliedToInjectionHost(appliedToInjectionHost);
}
fixes.add(action);
}
}
private boolean isSuppressed(@NotNull String toolId,
@NotNull InspectionSuppressor suppressor,
@NotNull PsiElement element) {
@@ -132,7 +167,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor);
return suppressors;
}
return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.<InspectionSuppressor>emptySet();
return elementLanguageSuppressor != null
? Collections.singleton(elementLanguageSuppressor)
: Collections.<InspectionSuppressor>emptySet();
}
public void cleanup(Project project) {
@@ -148,9 +185,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
protected volatile DefaultNameProvider myNameProvider = null;
/**
* @see com.intellij.codeInspection.InspectionEP#groupDisplayName
* @see com.intellij.codeInspection.InspectionEP#groupKey
* @see com.intellij.codeInspection.InspectionEP#groupBundle
* @see InspectionEP#groupDisplayName
* @see InspectionEP#groupKey
* @see InspectionEP#groupBundle
*/
@Nls
@NotNull
@@ -166,7 +203,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
}
/**
* @see com.intellij.codeInspection.InspectionEP#groupPath
* @see InspectionEP#groupPath
*/
@NotNull
public String[] getGroupPath() {
@@ -178,9 +215,9 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
}
/**
* @see com.intellij.codeInspection.InspectionEP#displayName
* @see com.intellij.codeInspection.InspectionEP#key
* @see com.intellij.codeInspection.InspectionEP#bundle
* @see InspectionEP#displayName
* @see InspectionEP#key
* @see InspectionEP#bundle
*/
@Nls
@NotNull
@@ -198,7 +235,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
/**
* DO NOT OVERRIDE this method.
*
* @see com.intellij.codeInspection.InspectionEP#shortName
* @see InspectionEP#shortName
*/
@NonNls
@NotNull
@@ -214,13 +251,13 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
@NotNull
public static String getShortName(@NotNull String className) {
return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"),"InspectionBase");
return StringUtil.trimEnd(StringUtil.trimEnd(className, "Inspection"), "InspectionBase");
}
/**
* DO NOT OVERRIDE this method.
*
* @see com.intellij.codeInspection.InspectionEP#level
* @see InspectionEP#level
*/
@NotNull
public HighlightDisplayLevel getDefaultLevel() {
@@ -230,7 +267,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
/**
* DO NOT OVERRIDE this method.
*
* @see com.intellij.codeInspection.InspectionEP#enabledByDefault
* @see InspectionEP#enabledByDefault
*/
public boolean isEnabledByDefault() {
return false;
@@ -238,6 +275,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
/**
* This method is called each time UI is shown.
*
* @return null if no UI options required.
*/
@Nullable
@@ -348,7 +386,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
* Initialize inspection with project. Is called on project opened for all profiles as well as on profile creation.
*
* @param project to be associated with this entry
* @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
* @deprecated this won't work for inspections configured via {@link InspectionEP}
*/
public void projectOpened(@NotNull Project project) {
}
@@ -357,7 +395,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
* Cleanup inspection settings corresponding to the project. Is called on project closed for all profiles as well as on profile deletion.
*
* @param project to be disassociated from this entry
* @deprecated this won't work for inspections configured via {@link com.intellij.codeInspection.InspectionEP}
* @deprecated this won't work for inspections configured via {@link InspectionEP}
*/
public void projectClosed(@NotNull Project project) {
}
@@ -411,7 +449,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
if (descriptionUrl == null) return null;
return ResourceUtil.loadText(descriptionUrl);
}
catch (IOException ignored) { }
catch (IOException ignored) {
}
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public interface HighlightInfoType {
@NonNls String UNUSED_SYMBOL_SHORT_NAME = "unused";
@NonNls String UNUSED_SYMBOL_DISPLAY_NAME = InspectionsBundle.message("inspection.dead.code.display.name");
@@ -201,4 +203,8 @@ public interface HighlightInfoType {
return myToolKey;
}
}
interface Iconable {
Icon getIcon();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@ import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
import com.intellij.ui.JBColor;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.concurrency.AtomicFieldUpdater;
import com.intellij.util.containers.ContainerUtil;
@@ -94,7 +93,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
myRendererColors.put(severity.getName(), renderColor);
}
myOrderMap = null;
HighlightDisplayLevel.registerSeverity(severity, getHighlightInfoTypeBySeverity(severity).getAttributesKey());
HighlightDisplayLevel.registerSeverity(severity, getHighlightInfoTypeBySeverity(severity).getAttributesKey(), null);
severitiesChanged();
}
@@ -17,9 +17,9 @@
package com.intellij.codeInsight.daemon.impl.actions;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInspection.InjectionAwareSuppressQuickFix;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.SuppressQuickFix;
import com.intellij.codeInspection.SuppressionUtil;
import com.intellij.icons.AllIcons;
import com.intellij.lang.Language;
@@ -32,6 +32,7 @@ import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,9 +44,10 @@ import java.util.List;
* @author Roman.Chernyatchik
* @date Aug 13, 2009
*/
public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements SuppressQuickFix, Iconable {
public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements InjectionAwareSuppressQuickFix, Iconable {
@NotNull protected final String myID;
private final boolean myReplaceOtherSuppressionIds;
private ThreeState myShouldBeAppliedToInjectionHost = ThreeState.UNSURE;
@Nullable
public abstract PsiElement getContainer(final PsiElement context);
@@ -60,6 +62,15 @@ public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements S
myReplaceOtherSuppressionIds = replaceOtherSuppressionIds;
}
public void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost) {
myShouldBeAppliedToInjectionHost = shouldBeAppliedToInjectionHost;
}
@Override
public ThreeState isShouldBeAppliedToInjectionHost() {
return myShouldBeAppliedToInjectionHost;
}
@NotNull
@Override
public String getName() {
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -59,9 +60,15 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction {
}
}
public ThreeState isShouldBeAppliedToInjectionHost() {
return myFix instanceof InjectionAwareSuppressQuickFix
? ((InjectionAwareSuppressQuickFix)myFix).isShouldBeAppliedToInjectionHost()
: ThreeState.UNSURE;
}
public PsiElement getContainer(PsiElement element) {
return myFix instanceof AbstractBatchSuppressByNoInspectionCommentFix
? ((AbstractBatchSuppressByNoInspectionCommentFix )myFix).getContainer(element) : null;
? ((AbstractBatchSuppressByNoInspectionCommentFix)myFix).getContainer(element) : null;
}
@Override
@@ -72,7 +79,7 @@ public class SuppressIntentionActionFromFix extends SuppressIntentionAction {
@NotNull
@Override
public String getText() {
return myFix.getName();
return myFix.getName() + (isShouldBeAppliedToInjectionHost() == ThreeState.NO ? " in injection" : "");
}
@NotNull
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -408,6 +408,10 @@ public class IconUtil {
}
@NotNull
public static Icon colorize(@NotNull final Icon source, @NotNull Color color) {
return colorize(source, color, false);
}
@NotNull
public static Icon colorize(@NotNull final Icon source, @NotNull Color color, boolean keepGray) {
@@ -427,7 +431,7 @@ public class IconUtil {
if (rgba[3] != 0) {
Color.RGBtoHSB(rgba[0], rgba[1], rgba[2], hsb);
int rgb = Color.HSBtoRGB(base[0], base[1] * (keepGray ? hsb[1] : 1f), base[2] * hsb[2]);
img.getRaster().setPixel(x, y, new int[]{(rgb >> 16) & 0xff, (rgb >> 8) & 0xff, rgb & 0xff, rgba[3]});
img.getRaster().setPixel(x, y, new int[]{rgb >> 16 & 0xff, rgb >> 8 & 0xff, rgb & 0xff, rgba[3]});
}
}
}
@@ -22,7 +22,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.InternalFileType;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
@@ -49,7 +48,7 @@ public class PsiManagerImpl extends PsiManagerEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiManagerImpl");
private final Project myProject;
private final FileIndexFacade myExcludedFileIndex;
private final FileIndexFacade myFileIndex;
private final MessageBus myMessageBus;
private final PsiModificationTracker myModificationTracker;
@@ -71,11 +70,11 @@ public class PsiManagerImpl extends PsiManagerEx {
public PsiManagerImpl(Project project,
FileDocumentManager fileDocumentManager,
PsiBuilderFactory psiBuilderFactory,
FileIndexFacade excludedFileIndex,
FileIndexFacade fileIndex,
MessageBus messageBus,
PsiModificationTracker modificationTracker) {
myProject = project;
myExcludedFileIndex = excludedFileIndex;
myFileIndex = fileIndex;
myMessageBus = messageBus;
myModificationTracker = modificationTracker;
@@ -84,7 +83,7 @@ public class PsiManagerImpl extends PsiManagerEx {
boolean isProjectDefault = project.isDefault();
myFileManager = isProjectDefault ? new EmptyFileManager(this) : new FileManagerImpl(this, fileDocumentManager, excludedFileIndex);
myFileManager = isProjectDefault ? new EmptyFileManager(this) : new FileManagerImpl(this, fileDocumentManager, fileIndex);
myTreeChangePreprocessors.add((PsiTreeChangePreprocessor)modificationTracker);
Collections.addAll(myTreeChangePreprocessors, Extensions.getExtensions(PsiTreeChangePreprocessor.EP_NAME, myProject));
@@ -131,10 +130,9 @@ public class PsiManagerImpl extends PsiManagerEx {
virtualFile = ((PsiFileSystemItem)element).getVirtualFile();
}
if (file != null && file.isPhysical() && virtualFile instanceof LightVirtualFile) return true;
if (virtualFile != null && virtualFile.getFileType() instanceof InternalFileType) return true;
if (virtualFile != null) {
return myExcludedFileIndex.isInContent(virtualFile);
return myFileIndex.isInContent(virtualFile);
}
return false;
}
@@ -62,7 +62,10 @@ public class StubTree extends ObjectStubTree<StubElement<?>> {
@NotNull
@Override
public List<StubElement<?>> getPlainListFromAllRoots() {
return ContainerUtil.concat(getRoot().getStubRoots(), new Function<PsiFileStub, Collection<? extends StubElement<?>>>() {
final PsiFileStub[] roots = getRoot().getStubRoots();
if (roots.length == 1) return super.getPlainListFromAllRoots();
return ContainerUtil.concat(roots, new Function<PsiFileStub, Collection<? extends StubElement<?>>>() {
@Override
public Collection<? extends StubElement<?>> fun(PsiFileStub stub) {
final ObjectStubTree existingTree = stub.getUserData(STUB_TO_TREE_REFERENCE);
@@ -83,20 +83,20 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode,
repoFixedWidth += checkBoxWidth;
if (myCheckBoxHGap > 0) {
renderer.append("");
renderer.appendFixedTextFragmentWidth(checkBoxWidth + renderer.getIconTextGap() + borderHOffset);
renderer.appendTextPadding(checkBoxWidth + renderer.getIconTextGap() + borderHOffset);
}
}
else {
if (myCheckBoxHGap <= 0) {
renderer.append("");
renderer.appendFixedTextFragmentWidth(myRepositoryPanel.calculateRendererShiftH(renderer));
renderer.appendTextPadding(myRepositoryPanel.calculateRendererShiftH(renderer));
}
}
SimpleTextAttributes repositoryDetailsTextAttributes = PushLogTreeUtil
.addTransparencyIfNeeded(SimpleTextAttributes.REGULAR_ATTRIBUTES, isChecked());
renderer.append(getRepoName(renderer, repoFixedWidth), repositoryDetailsTextAttributes);
renderer.appendFixedTextFragmentWidth(repoFixedWidth);
renderer.appendTextPadding(repoFixedWidth);
renderer.append(myRepositoryPanel.getSourceName(), repositoryDetailsTextAttributes);
renderer.append(myRepositoryPanel.getArrow(), repositoryDetailsTextAttributes);
PushTargetPanel pushTargetPanel = myRepositoryPanel.getTargetPanel();
@@ -147,10 +147,10 @@ public class RepositoryWithBranchPanel<T extends PushTarget> extends NonOpaquePa
myRepositoryCheckbox.setVisible(true);
if (myCheckBoxLoadingIconGapH < 0) {
myTextRenderer.append("");
myTextRenderer.appendFixedTextFragmentWidth(calculateRendererShiftH(myTextRenderer));
myTextRenderer.appendTextPadding(calculateRendererShiftH(myTextRenderer));
}
myTextRenderer.append(getRepositoryName(), SimpleTextAttributes.GRAY_ATTRIBUTES);
myTextRenderer.appendFixedTextFragmentWidth(120);
myTextRenderer.appendTextPadding(120);
}
else {
myRepositoryCheckbox.setVisible(false);
Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

After

Width:  |  Height:  |  Size: 92 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 B

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

After

Width:  |  Height:  |  Size: 108 B

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 B

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Some files were not shown because too many files have changed in this diff Show More