mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+2
-1
@@ -31,6 +31,7 @@ import com.intellij.psi.presentation.java.ClassPresentationUtil;
|
||||
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.content.impl.ContentImpl;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -79,7 +80,7 @@ public class InternalCompilerRefServiceView extends JPanel implements DataProvid
|
||||
}
|
||||
});
|
||||
setLayout(new BorderLayout());
|
||||
add(myTree);
|
||||
add(new JBScrollPane(myTree));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
-49
@@ -445,55 +445,6 @@ public class AnnotationsHighlightUtil {
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HighlightInfo checkForeignInnerClassesUsed(final PsiAnnotation annotation) {
|
||||
final HighlightInfo[] infos = new HighlightInfo[1];
|
||||
final PsiAnnotationOwner owner = annotation.getOwner();
|
||||
if (owner instanceof PsiModifierList) {
|
||||
final PsiElement parent = ((PsiModifierList)owner).getParent();
|
||||
if (parent instanceof PsiClass) {
|
||||
annotation.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (infos[0] != null) return;
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
super.visitClassObjectAccessExpression(expression);
|
||||
final PsiTypeElement operand = expression.getOperand();
|
||||
final PsiClass classType = PsiUtil.resolveClassInType(operand.getType());
|
||||
if (classType != null) {
|
||||
checkAccessibility(operand.getInnermostComponentReferenceElement(), classType, HighlightUtil.formatClass(classType));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement resolve = expression.resolve();
|
||||
if (resolve instanceof PsiField) {
|
||||
checkAccessibility(expression, (PsiMember)resolve, HighlightUtil.formatField((PsiField)resolve));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAccessibility(PsiJavaCodeReferenceElement expression, PsiMember resolve, String memberString) {
|
||||
if (resolve.hasModifierProperty(PsiModifier.PRIVATE) &&
|
||||
PsiTreeUtil.isAncestor(parent, resolve, true)) {
|
||||
String description = JavaErrorMessages.message("private.symbol",
|
||||
memberString,
|
||||
HighlightUtil.formatClass((PsiClass)parent));
|
||||
infos[0] =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
|
||||
HighlightUtil.registerAccessQuickFixAction(resolve, expression, infos[0], null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return infos[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkAnnotationType(PsiAnnotation annotation) {
|
||||
PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
|
||||
|
||||
+1
-1
@@ -635,7 +635,7 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
|
||||
if (superMethod.hasModifierProperty(PsiModifier.STATIC) && superContainingClass != null &&
|
||||
superContainingClass.isInterface() && PsiUtil.isLanguageLevel8OrHigher(superContainingClass)) {
|
||||
superContainingClass.isInterface() && !checkEqualsSuper && PsiUtil.isLanguageLevel8OrHigher(superContainingClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -241,7 +241,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation));
|
||||
if (CommonClassNames.JAVA_LANG_OVERRIDE.equals(annotation.getQualifiedName())) {
|
||||
|
||||
+15
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,17 +22,15 @@ package com.intellij.refactoring.rename.naming;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AutomaticOverloadsRenamer extends AutomaticRenamer {
|
||||
public AutomaticOverloadsRenamer(PsiMethod method, String newName) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
final PsiMethod[] overloads = containingClass.findMethodsByName(method.getName(), false);
|
||||
for (PsiMethod overload : overloads) {
|
||||
if (overload != method && overload.findDeepestSuperMethods().length == 0) {
|
||||
myElements.add(overload);
|
||||
suggestAllNames(overload.getName(), newName);
|
||||
}
|
||||
|
||||
public AutomaticOverloadsRenamer(@NotNull PsiMethod method, String newName) {
|
||||
for (PsiMethod overload : getOverloads(method)) {
|
||||
if (overload != method && overload.findDeepestSuperMethods().length == 0) {
|
||||
myElements.add(overload);
|
||||
suggestAllNames(overload.getName(), newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,4 +52,11 @@ public class AutomaticOverloadsRenamer extends AutomaticRenamer {
|
||||
public boolean isSelectedByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected PsiMethod[] getOverloads(@NotNull PsiMethod method) {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return PsiMethod.EMPTY_ARRAY;
|
||||
return containingClass.findMethodsByName(method.getName(), false);
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,16 +20,21 @@
|
||||
*/
|
||||
package com.intellij.refactoring.rename.naming;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class AutomaticOverloadsRenamerFactory implements AutomaticRenamerFactory{
|
||||
public boolean isApplicable(PsiElement element) {
|
||||
if (element instanceof PsiMethod && !((PsiMethod)element).isConstructor()) {
|
||||
public class AutomaticOverloadsRenamerFactory implements AutomaticRenamerFactory {
|
||||
|
||||
public boolean isApplicable(@NotNull PsiElement element) {
|
||||
if (element.getLanguage() == JavaLanguage.INSTANCE && element instanceof PsiMethod && !((PsiMethod)element).isConstructor()) {
|
||||
final PsiClass containingClass = ((PsiMethod)element).getContainingClass();
|
||||
return containingClass != null && containingClass.findMethodsByName(((PsiMethod)element).getName(), false).length > 1;
|
||||
}
|
||||
@@ -48,6 +53,7 @@ public class AutomaticOverloadsRenamerFactory implements AutomaticRenamerFactory
|
||||
JavaRefactoringSettings.getInstance().setRenameOverloads(enabled);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public AutomaticRenamer createRenamer(PsiElement element, String newName, Collection<UsageInfo> usages) {
|
||||
return new AutomaticOverloadsRenamer((PsiMethod)element, newName);
|
||||
}
|
||||
|
||||
@@ -122,9 +122,15 @@ public class JavaResolveUtil {
|
||||
if (memberClass == null) {
|
||||
return false;
|
||||
}
|
||||
// if resolving supertype reference, skip its containing class with getContextClass
|
||||
PsiClass contextClass = member instanceof PsiClass ? getContextClass(place)
|
||||
: PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
|
||||
PsiClass contextClass;
|
||||
if (member instanceof PsiClass) {
|
||||
// if resolving supertype reference, skip its containing class with getContextClass
|
||||
contextClass = getContextClass(place);
|
||||
}
|
||||
else {
|
||||
contextClass = PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
|
||||
if (isInClassAnnotationParameterList(place, contextClass)) return false;
|
||||
}
|
||||
while (contextClass != null) {
|
||||
if (InheritanceUtil.isInheritorOrSelf(contextClass, memberClass, true)) {
|
||||
if (member instanceof PsiClass ||
|
||||
@@ -156,7 +162,8 @@ public class JavaResolveUtil {
|
||||
if (fileResolveScope == null) {
|
||||
PsiClass placeTopLevelClass = getTopLevelClass(place, null);
|
||||
PsiClass memberTopLevelClass = getTopLevelClass(memberClass, null);
|
||||
return manager.areElementsEquivalent(placeTopLevelClass, memberTopLevelClass);
|
||||
return manager.areElementsEquivalent(placeTopLevelClass, memberTopLevelClass) &&
|
||||
!isInClassAnnotationParameterList(place, PsiTreeUtil.getContextOfType(place, PsiClass.class, false));
|
||||
}
|
||||
else {
|
||||
return fileResolveScope instanceof PsiClass &&
|
||||
@@ -186,6 +193,16 @@ public class JavaResolveUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isInClassAnnotationParameterList(@NotNull PsiElement place, @Nullable PsiClass contextClass) {
|
||||
if (contextClass != null) {
|
||||
PsiAnnotation annotation = PsiTreeUtil.getContextOfType(place, PsiAnnotation.class, true);
|
||||
if (annotation != null && contextClass.getModifierList() == annotation.getOwner()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean ignoreReferencedElementAccessibility(PsiFile placeFile) {
|
||||
return placeFile instanceof FileResolveScopeProvider &&
|
||||
((FileResolveScopeProvider) placeFile).ignoreReferencedElementAccessibility() &&
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import a.A;
|
||||
|
||||
@SuppressWarnings(A.<error descr="'A_FOO' has protected access in 'a.A'">A_FOO</error>)
|
||||
class B extends A {}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@SomeAnnotation(<error descr="'Foo.Bar' has private access in 'Foo'">Foo.Bar</error>.class)
|
||||
@SomeAnnotation(Foo.<error descr="'Foo.Bar' has private access in 'Foo'">Bar</error>.class)
|
||||
public class Foo{
|
||||
private static class Bar {
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@SuppressWarnings(<error descr="'ThisClass.FOO' has private access in 'ThisClass'">ThisClass.FOO</error>)
|
||||
@SuppressWarnings(ThisClass.<error descr="'FOO' has private access in 'ThisClass'">FOO</error>)
|
||||
public class ThisClass {
|
||||
private static final String FOO = "foo";
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@FooAnnotation(<error descr="'Foo.BAR' has private access in 'Foo'">Foo.BAR</error>)
|
||||
@FooAnnotation(Foo.<error descr="'BAR' has private access in 'Foo'">BAR</error>)
|
||||
class Foo {
|
||||
private static final String BAR = "bar";
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
interface Test {
|
||||
<error descr="'foo(A)' clashes with 'foo(B)'; both methods have same erasure">static <A, B> void foo(A a)</error> {}
|
||||
static <A, B> void foo(B b) {}
|
||||
}
|
||||
+6
@@ -99,6 +99,12 @@ public class LightAdvHighlightingFixtureTest extends LightCodeInsightFixtureTest
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
public void testProtectedFieldUsedInAnnotationParameterOfInheritor() throws Exception {
|
||||
myFixture.addClass("package a; public class A {protected final static String A_FOO = \"A\";}");
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/advFixture";
|
||||
|
||||
+4
@@ -1012,4 +1012,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testBoundsPromotionForDerivedType() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSameErasureForStaticMethodsInInterfaces() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +31,11 @@ public class FlipCommaIntentionTest extends IPPTestCase {
|
||||
" int b, a;\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testUnavailableForDangling() throws Exception {
|
||||
myFixture.configureByText("a.java", "class C {\n" +
|
||||
" int a[] = new int[]{1,2,<caret>};" +
|
||||
"}");
|
||||
assertEmpty(myFixture.filterAvailableIntentions("Flip"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,24 +16,18 @@
|
||||
package org.jetbrains.jps.javac;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.ExtensionsSupport;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 09-Nov-16
|
||||
*/
|
||||
public abstract class JavaCompilerToolExtension {
|
||||
@NotNull
|
||||
public abstract String getId();
|
||||
|
||||
/**
|
||||
/**
|
||||
* This method is called before compiler task execution.
|
||||
* The extension can install all necessary compiler listeners here.
|
||||
*
|
||||
@@ -45,31 +39,9 @@ public abstract class JavaCompilerToolExtension {
|
||||
public void beforeCompileTaskExecution(@NotNull JavaCompilingTool compilingTool, @NotNull JavaCompiler.CompilationTask task, @NotNull Collection<String> options, @NotNull DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom data passed through DiagnosticOutputConsumer object with pluginId == thisExtensionId will be passed to this method
|
||||
* @param dataName
|
||||
* @param content
|
||||
*/
|
||||
public void processData(String dataName, byte[] content) {
|
||||
}
|
||||
|
||||
public List<String> getExternalBuildProcessOptions(@NotNull JavaCompilingTool compilingTool) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static final ExtensionsSupport<JavaCompilerToolExtension> ourExtSupport = new ExtensionsSupport<JavaCompilerToolExtension>(JavaCompilerToolExtension.class);
|
||||
@NotNull
|
||||
public static Collection<JavaCompilerToolExtension> getExtensions() {
|
||||
return ourExtSupport.getExtensions();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JavaCompilerToolExtension getExtension(@NotNull String id) {
|
||||
for (JavaCompilerToolExtension extension : getExtensions()) {
|
||||
if (id.equals(extension.getId())) {
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ public class JavacMain {
|
||||
extension.beforeCompileTaskExecution(compilingTool, task, _options, diagnosticConsumer);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
fileManager.getContext().reportMessage(Diagnostic.Kind.MANDATORY_WARNING, extension.getId() + ": " + e.getMessage());
|
||||
fileManager.getContext().reportMessage(Diagnostic.Kind.MANDATORY_WARNING, extension.getClass() + " : " + e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.jps.javac.ast.JavacAstCustomDataListener
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.jps.javac.ast.ReferenceCollectorExternalJavacOptionsProvider
|
||||
+2
-16
@@ -1,16 +1,2 @@
|
||||
#
|
||||
# Copyright 2000-2016 JetBrains s.r.o.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
org.jetbrains.jps.javac.ast.RefCollectorCompilerToolExtension
|
||||
org.jetbrains.jps.javac.ast.ExternalRefCollectorCompilerToolExtension
|
||||
org.jetbrains.jps.javac.ast.InProcessRefCollectorCompilerToolExtension
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.incremental.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An extension for processing custom messages that had been sent by {@link org.jetbrains.jps.javac.DiagnosticOutputConsumer#customOutputData}
|
||||
*/
|
||||
public interface CustomOutputDataListener {
|
||||
|
||||
@NotNull
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Custom data passed through DiagnosticOutputConsumer object with pluginId == thisExtension.getId() will be passed to this method
|
||||
* @param dataName
|
||||
* @param content
|
||||
*/
|
||||
void processData(@Nullable String dataName, @NotNull byte[] content);
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.incremental.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An extension for setting up additional options for external java compiler.
|
||||
* See {@link JavaBuilder#loadCommonJavacOptions(org.jetbrains.jps.incremental.CompileContext, JavaCompilingTool)}
|
||||
*/
|
||||
public interface ExternalJavacOptionsProvider {
|
||||
@NotNull
|
||||
Collection<String> getOptions(@NotNull JavaCompilingTool tool);
|
||||
}
|
||||
|
||||
@@ -1047,8 +1047,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
for (JavaCompilerToolExtension extension : JavaCompilerToolExtension.getExtensions()) {
|
||||
vmOptions.addAll(extension.getExternalBuildProcessOptions(compilingTool));
|
||||
for (ExternalJavacOptionsProvider extension : JpsServiceManager.getInstance().getExtensions(ExternalJavacOptionsProvider.class)) {
|
||||
vmOptions.addAll(extension.getOptions(compilingTool));
|
||||
}
|
||||
|
||||
if (JavaCompilers.ECLIPSE_ID.equals(compilingTool.getId())) {
|
||||
@@ -1119,9 +1119,11 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
|
||||
@Override
|
||||
public void customOutputData(String pluginId, String dataName, byte[] data) {
|
||||
final JavaCompilerToolExtension handler = JavaCompilerToolExtension.getExtension(pluginId);
|
||||
if (handler != null) {
|
||||
handler.processData(dataName, data);
|
||||
for (CustomOutputDataListener listener : JpsServiceManager.getInstance().getExtensions(CustomOutputDataListener.class)) {
|
||||
if (pluginId.equals(listener.getId())) {
|
||||
listener.processData(dataName, data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
import org.jetbrains.jps.javac.DiagnosticOutputConsumer;
|
||||
import org.jetbrains.jps.javac.JavaCompilerToolExtension;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class AbstractRefCollectorCompilerToolExtension extends JavaCompilerToolExtension {
|
||||
@Override
|
||||
public final void beforeCompileTaskExecution(@NotNull JavaCompilingTool compilingTool,
|
||||
@NotNull JavaCompiler.CompilationTask task,
|
||||
@NotNull Collection<String> options,
|
||||
@NotNull DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
if (isEnabled()) {
|
||||
JavacReferenceCollector.installOn(task, divideImportsRefs(), getFileDataConsumer(diagnosticConsumer));
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isEnabled();
|
||||
|
||||
protected abstract boolean divideImportsRefs();
|
||||
|
||||
@NotNull
|
||||
protected abstract Consumer<JavacFileData> getFileDataConsumer(@NotNull DiagnosticOutputConsumer diagnosticConsumer);
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.javac.DiagnosticOutputConsumer;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
|
||||
public class ExternalRefCollectorCompilerToolExtension extends AbstractRefCollectorCompilerToolExtension {
|
||||
public static final String ID = "external.ast.reference.collector";
|
||||
|
||||
public static final String ENABLED_PARAM = "external.java.process.ref.collector.enabled";
|
||||
public static final String DIVIDE_IMPORTS_PARAM = "external.java.process.divide.imports";
|
||||
|
||||
@Override
|
||||
protected boolean isEnabled() {
|
||||
return "true".equals(System.getProperty(ENABLED_PARAM));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean divideImportsRefs() {
|
||||
return "true".equals(System.getProperty(DIVIDE_IMPORTS_PARAM));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Consumer<JavacFileData> getFileDataConsumer(@NotNull final DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
return new Consumer<JavacFileData>() {
|
||||
@Override
|
||||
public void consume(JavacFileData data) {
|
||||
diagnosticConsumer.customOutputData(ID, "javac-refs", data.asBytes());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.javac.DiagnosticOutputConsumer;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileReferencesRegistrar;
|
||||
import org.jetbrains.jps.service.JpsServiceManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class InProcessRefCollectorCompilerToolExtension extends AbstractRefCollectorCompilerToolExtension {
|
||||
@Override
|
||||
protected boolean isEnabled() {
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
final Class<JpsServiceManager> jpsServiceManager = JpsServiceManager.class;
|
||||
}
|
||||
catch (NoClassDefFoundError ignored) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (JavacFileReferencesRegistrar registrar : JpsServiceManager.getInstance().getExtensions(JavacFileReferencesRegistrar.class)) {
|
||||
if (registrar.isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean divideImportsRefs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Consumer<JavacFileData> getFileDataConsumer(@NotNull DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
return createFileDataConsumer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static Consumer<JavacFileData> createFileDataConsumer() {
|
||||
return new JavacFileDataConsumer();
|
||||
}
|
||||
|
||||
private static class JavacFileDataConsumer implements Consumer<JavacFileData> {
|
||||
final JavacFileReferencesRegistrar[] myRegistrars;
|
||||
|
||||
private JavacFileDataConsumer() {
|
||||
List<JavacFileReferencesRegistrar> registrars = new ArrayList<JavacFileReferencesRegistrar>();
|
||||
for (JavacFileReferencesRegistrar registrar : JpsServiceManager.getInstance().getExtensions(JavacFileReferencesRegistrar.class)) {
|
||||
if (registrar.isEnabled()) {
|
||||
registrar.initialize();
|
||||
registrars.add(registrar);
|
||||
}
|
||||
}
|
||||
myRegistrars = registrars.toArray(new JavacFileReferencesRegistrar[registrars.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume(JavacFileData data) {
|
||||
for (JavacFileReferencesRegistrar registrar : myRegistrars) {
|
||||
if (registrar.isEnabled()) {
|
||||
registrar.registerFile(data.getFilePath(), registrar.onlyImports() ? data.getImportRefs() : data.getRefs(), data.getDefs());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.incremental.java.CustomOutputDataListener;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
|
||||
public class JavacAstCustomDataListener implements CustomOutputDataListener {
|
||||
private final Consumer<JavacFileData> myConsumer;
|
||||
|
||||
public JavacAstCustomDataListener() {
|
||||
myConsumer = InProcessRefCollectorCompilerToolExtension.createFileDataConsumer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getId() {
|
||||
return ExternalRefCollectorCompilerToolExtension.ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processData(@Nullable String dataName, @NotNull byte[] content) {
|
||||
myConsumer.consume(JavacFileData.fromBytes(content));
|
||||
}
|
||||
}
|
||||
+10
-14
@@ -15,20 +15,17 @@
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.sun.source.tree.*;
|
||||
import com.sun.source.util.*;
|
||||
import com.sun.tools.javac.util.ClientCodeException;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacDef;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacRef;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacNameTable;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacRef;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
@@ -51,21 +48,19 @@ final class JavacReferenceCollectorListener implements TaskListener {
|
||||
private final Trees myTreeUtility;
|
||||
private final JavacNameTable myNameTableCache;
|
||||
|
||||
private NotNullLazyValue<Name> myAsterisk = new NotNullLazyValue<Name>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected Name compute() {
|
||||
return myElementUtility.getName("*");
|
||||
}
|
||||
};
|
||||
|
||||
private final Map<String, ReferenceCollector> myIncompletelyProcessedFiles = new THashMap<String, ReferenceCollector>(10);
|
||||
|
||||
static void installOn(JavaCompiler.CompilationTask task,
|
||||
boolean divideImportRefs,
|
||||
Consumer<JavacFileData> dataConsumer) {
|
||||
JavacTask javacTask = (JavacTask)task;
|
||||
Method addTaskMethod = ReflectionUtil.getMethod(JavacTask.class, "addTaskListener", TaskListener.class); // jdk >= 8
|
||||
Method addTaskMethod; // jdk >= 8
|
||||
try {
|
||||
addTaskMethod = JavacTask.class.getMethod("addTaskListener", TaskListener.class);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
final JavacReferenceCollectorListener taskListener = new JavacReferenceCollectorListener(divideImportRefs,
|
||||
dataConsumer,
|
||||
javacTask.getElements(),
|
||||
@@ -73,6 +68,7 @@ final class JavacReferenceCollectorListener implements TaskListener {
|
||||
Trees.instance(javacTask));
|
||||
if (addTaskMethod != null) {
|
||||
try {
|
||||
addTaskMethod.setAccessible(true);
|
||||
addTaskMethod.invoke(task, taskListener);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
@@ -178,7 +174,7 @@ final class JavacReferenceCollectorListener implements TaskListener {
|
||||
final MemberSelectTree classImport = (MemberSelectTree)qExpr;
|
||||
final Element ownerElement = incompletelyProcessedFile.getReferencedElement(classImport);
|
||||
final Name name = id.getIdentifier();
|
||||
if (name != myAsterisk.getValue()) {
|
||||
if (name != myNameTableCache.getAsterisk()) {
|
||||
// member import
|
||||
for (Element memberElement : myElementUtility.getAllMembers((TypeElement)ownerElement)) {
|
||||
if (memberElement.getSimpleName() == name) {
|
||||
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import com.intellij.openapi.util.AtomicClearableLazyValue;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
import org.jetbrains.jps.javac.DiagnosticOutputConsumer;
|
||||
import org.jetbrains.jps.javac.JavaCompilerToolExtension;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileData;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileReferencesRegistrar;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
import org.jetbrains.jps.service.JpsServiceManager;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 09-Nov-16
|
||||
*/
|
||||
public class RefCollectorCompilerToolExtension extends JavaCompilerToolExtension{
|
||||
public static final String ID = "ASTReferenceCollector";
|
||||
|
||||
private static final String ENABLED_PARAM = "jps.ref.collector.enabled";
|
||||
private static final String DIVIDE_IMPORTS_PARAM = "jps.divide.imports";
|
||||
|
||||
private final AtomicClearableLazyValue<List<JavacFileReferencesRegistrar>> myRegistrars = new AtomicClearableLazyValue<List<JavacFileReferencesRegistrar>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<JavacFileReferencesRegistrar> compute() {
|
||||
List<JavacFileReferencesRegistrar> result = new ArrayList<JavacFileReferencesRegistrar>();
|
||||
for (JavacFileReferencesRegistrar registrar : JpsServiceManager.getInstance().getExtensions(JavacFileReferencesRegistrar.class)) {
|
||||
if (registrar.isEnabled()) {
|
||||
registrar.initialize();
|
||||
result.add(registrar);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeCompileTaskExecution(@NotNull JavaCompilingTool compilingTool,
|
||||
@NotNull JavaCompiler.CompilationTask task,
|
||||
@NotNull Collection<String> options,
|
||||
@NotNull final DiagnosticOutputConsumer diagnosticConsumer) {
|
||||
if (isJavac(compilingTool)) {
|
||||
final String isEnabledProperty = System.getProperty(ENABLED_PARAM);
|
||||
|
||||
Consumer<JavacFileData> fileDataConsumer;
|
||||
boolean divideImportsRefs;
|
||||
if (isEnabledProperty == null) {
|
||||
//in-process
|
||||
final RefCollectorOptions refCollectorOptions = new RefCollectorOptions();
|
||||
fileDataConsumer = refCollectorOptions.enabled ? new Consumer<JavacFileData>() {
|
||||
@Override
|
||||
public void consume(JavacFileData data) {
|
||||
submitFileData(data);
|
||||
}
|
||||
} : null;
|
||||
divideImportsRefs = refCollectorOptions.divideImportRefs;
|
||||
} else if (isEnabledProperty.equals("true")) {
|
||||
//external
|
||||
fileDataConsumer = new Consumer<JavacFileData>() {
|
||||
@Override
|
||||
public void consume(JavacFileData data) {
|
||||
diagnosticConsumer.customOutputData(ID, "javac-refs", data.asBytes());
|
||||
}
|
||||
};
|
||||
divideImportsRefs = SystemProperties.getBooleanProperty(DIVIDE_IMPORTS_PARAM, false);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileDataConsumer != null) {
|
||||
JavacReferenceCollector.installOn(task, divideImportsRefs, fileDataConsumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getExternalBuildProcessOptions(@NotNull JavaCompilingTool compilingTool) {
|
||||
List<String> options = new ArrayList<String>(2);
|
||||
if (isJavac(compilingTool)) {
|
||||
final RefCollectorOptions refCollectorOptions = new RefCollectorOptions();
|
||||
options.add("-D" + ENABLED_PARAM + "=" + refCollectorOptions.enabled);
|
||||
if (refCollectorOptions.enabled && refCollectorOptions.divideImportRefs) {
|
||||
options.add("-D" + DIVIDE_IMPORTS_PARAM + "=true");
|
||||
}
|
||||
} else {
|
||||
options.add("-D" + ENABLED_PARAM + "=false");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processData(String dataName, byte[] content) {
|
||||
submitFileData(JavacFileData.fromBytes(content));
|
||||
}
|
||||
|
||||
private void submitFileData(@NotNull JavacFileData data) {
|
||||
for (JavacFileReferencesRegistrar registrar : myRegistrars.getValue()) {
|
||||
registrar.registerFile(data.getFilePath(), registrar.onlyImports() ? data.getImportRefs() : data.getRefs(), data.getDefs());
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJavac(@NotNull JavaCompilingTool compilingTool) {
|
||||
return JavaCompilers.JAVAC_ID.equals(compilingTool.getId());
|
||||
}
|
||||
|
||||
private static class RefCollectorOptions {
|
||||
private final boolean enabled;
|
||||
private final boolean divideImportRefs;
|
||||
|
||||
private RefCollectorOptions() {
|
||||
boolean enabled = false;
|
||||
boolean divideImportRefs = false;
|
||||
for (JavacFileReferencesRegistrar listener : JpsServiceManager.getInstance().getExtensions(JavacFileReferencesRegistrar.class)) {
|
||||
if (listener.isEnabled()) {
|
||||
enabled = true;
|
||||
if (listener.onlyImports()) {
|
||||
divideImportRefs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.enabled = enabled;
|
||||
this.divideImportRefs = divideImportRefs;
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void clearRegistrars() {
|
||||
myRegistrars.drop();
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.jps.javac.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.java.JavaCompilingTool;
|
||||
import org.jetbrains.jps.incremental.java.ExternalJavacOptionsProvider;
|
||||
import org.jetbrains.jps.javac.ast.api.JavacFileReferencesRegistrar;
|
||||
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
|
||||
import org.jetbrains.jps.service.JpsServiceManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ReferenceCollectorExternalJavacOptionsProvider implements ExternalJavacOptionsProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<String> getOptions(@NotNull JavaCompilingTool tool) {
|
||||
List<String> options = new ArrayList<String>(2);
|
||||
if (tool.getId().equals(JavaCompilers.JAVAC_ID)) {
|
||||
final JavacReferenceCollectorOptions
|
||||
javacReferenceCollectorOptions = new JavacReferenceCollectorOptions();
|
||||
options.add("-D" + ExternalRefCollectorCompilerToolExtension.ENABLED_PARAM + "=" + javacReferenceCollectorOptions.isEnabled());
|
||||
if (javacReferenceCollectorOptions.isEnabled() && javacReferenceCollectorOptions.isImportRefsDivided()) {
|
||||
options.add("-D" + ExternalRefCollectorCompilerToolExtension.DIVIDE_IMPORTS_PARAM + "=true");
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private static class JavacReferenceCollectorOptions {
|
||||
private final boolean myEnabled;
|
||||
private final boolean myDivideImportRefs;
|
||||
|
||||
private JavacReferenceCollectorOptions() {
|
||||
boolean enabled = false;
|
||||
boolean divideImportRefs = false;
|
||||
for (JavacFileReferencesRegistrar listener : JpsServiceManager.getInstance().getExtensions(JavacFileReferencesRegistrar.class)) {
|
||||
if (listener.isEnabled()) {
|
||||
enabled = true;
|
||||
if (listener.onlyImports()) {
|
||||
divideImportRefs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myEnabled = enabled;
|
||||
myDivideImportRefs = divideImportRefs;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return myEnabled;
|
||||
}
|
||||
|
||||
public boolean isImportRefsDivided() {
|
||||
return myDivideImportRefs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,20 @@
|
||||
package org.jetbrains.jps.javac.ast.api;
|
||||
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.util.ThrowableConsumer;
|
||||
import com.intellij.util.io.*;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class JavacFileData {
|
||||
private static final byte CLASS_MARKER = 0;
|
||||
private static final byte METHOD_MARKER = 1;
|
||||
private static final byte FIELD_MARKER = 2;
|
||||
private static final byte FUN_EXPR_MARKER = 3;
|
||||
|
||||
private final String myFilePath;
|
||||
private final Collection<JavacRef> myRefs;
|
||||
private final Collection<JavacRef> myImportRefs;
|
||||
@@ -66,10 +67,13 @@ public class JavacFileData {
|
||||
|
||||
@NotNull
|
||||
public byte[] asBytes() {
|
||||
final BufferExposingByteArrayOutputStream os = new BufferExposingByteArrayOutputStream();
|
||||
final ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
DataOutputStream stream = new DataOutputStream(os);
|
||||
try {
|
||||
EXTERNALIZER.save(stream, this);
|
||||
stream.writeUTF(getFilePath());
|
||||
saveRefs(stream, getRefs());
|
||||
saveRefs(stream, getImportRefs());
|
||||
saveDefs(stream, getDefs());
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -79,177 +83,140 @@ public class JavacFileData {
|
||||
|
||||
@NotNull
|
||||
public static JavacFileData fromBytes(byte[] bytes) {
|
||||
final UnsyncByteArrayInputStream is = new UnsyncByteArrayInputStream(bytes);
|
||||
final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
|
||||
try {
|
||||
return EXTERNALIZER.read(new DataInputStream(is));
|
||||
return new JavacFileData(in.readUTF(),
|
||||
readRefs(in),
|
||||
readRefs(in),
|
||||
readDefs(in));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final DataExternalizer<JavacFileData> EXTERNALIZER = new DataExternalizer<JavacFileData>() {
|
||||
DataExternalizer<JavacRef> myRefSeqExternalizer = createRefExternalizer();
|
||||
DataExternalizer<JavacDef> myDefSeqExternalizer = createDefExternalizer();
|
||||
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, JavacFileData data) throws IOException {
|
||||
EnumeratorStringDescriptor.INSTANCE.save(out, data.getFilePath());
|
||||
saveRefs(out, data.getRefs());
|
||||
saveRefs(out, data.getImportRefs());
|
||||
saveDefs(out, data.getDefs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavacFileData read(@NotNull DataInput in) throws IOException {
|
||||
return new JavacFileData(EnumeratorStringDescriptor.INSTANCE.read(in),
|
||||
readRefs(in),
|
||||
readRefs(in),
|
||||
readDefs(in));
|
||||
}
|
||||
|
||||
|
||||
private void saveRefs(final DataOutput out, Collection<JavacRef> refs) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(out, refs, new ThrowableConsumer<JavacRef, IOException>() {
|
||||
@Override
|
||||
public void consume(JavacRef ref) throws IOException {
|
||||
myRefSeqExternalizer.save(out, ref);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Collection<JavacRef> readRefs(final DataInput in) throws IOException {
|
||||
return DataInputOutputUtil.readSeq(in, new ThrowableComputable<JavacRef, IOException>() {
|
||||
@Override
|
||||
public JavacRef compute() throws IOException {
|
||||
return myRefSeqExternalizer.read(in);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveDefs(final DataOutput out, List<JavacDef> defs) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(out, defs, new ThrowableConsumer<JavacDef, IOException>() {
|
||||
@Override
|
||||
public void consume(JavacDef def) throws IOException {
|
||||
myDefSeqExternalizer.save(out, def);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<JavacDef> readDefs(final DataInput in) throws IOException {
|
||||
return DataInputOutputUtil.readSeq(in, new ThrowableComputable<JavacDef, IOException>() {
|
||||
@Override
|
||||
public JavacDef compute() throws IOException {
|
||||
return myDefSeqExternalizer.read(in);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private static DataExternalizer<JavacDef> createDefExternalizer() {
|
||||
return new DataExternalizer<JavacDef>() {
|
||||
private static final byte CLASS_MARKER = 0;
|
||||
private static final byte FUN_EXPR_MARKER = 1;
|
||||
|
||||
DataExternalizer<JavacRef> refExternalizer = createRefExternalizer();
|
||||
|
||||
private static void saveRefs(final DataOutput out, Collection<JavacRef> refs) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(out, refs, new ThrowableConsumer<JavacRef, IOException>() {
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, JavacDef def) throws IOException {
|
||||
if (def instanceof JavacDef.JavacClassDef) {
|
||||
out.writeByte(CLASS_MARKER);
|
||||
final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
|
||||
out.writeInt(superClasses.length);
|
||||
for (JavacRef aClass : superClasses) {
|
||||
refExternalizer.save(out, aClass);
|
||||
}
|
||||
}
|
||||
else if (def instanceof JavacDef.JavacFunExprDef) {
|
||||
out.writeByte(FUN_EXPR_MARKER);
|
||||
} else {
|
||||
throw new IllegalStateException("unknown type: " + def.getClass());
|
||||
}
|
||||
refExternalizer.save(out, def.getDefinedElement());
|
||||
public void consume(JavacRef ref) throws IOException {
|
||||
writeJavacRef(out, ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavacDef read(@NotNull DataInput in) throws IOException {
|
||||
final byte marker = in.readByte();
|
||||
switch (marker) {
|
||||
case CLASS_MARKER:
|
||||
final int supersSize = in.readInt();
|
||||
JavacRef[] superClasses = new JavacRef[supersSize];
|
||||
for (int i = 0; i < supersSize; i++) {
|
||||
superClasses[i] = refExternalizer.read(in);
|
||||
}
|
||||
return new JavacDef.JavacClassDef(refExternalizer.read(in), superClasses);
|
||||
case FUN_EXPR_MARKER:
|
||||
return new JavacDef.JavacFunExprDef(refExternalizer.read(in));
|
||||
default: throw new IllegalStateException("unknown marker " + marker);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private static DataExternalizer<JavacRef> createRefExternalizer() {
|
||||
return new DataExternalizer<JavacRef>() {
|
||||
private static final byte CLASS_MARKER = 0;
|
||||
private static final byte METHOD_MARKER = 1;
|
||||
private static final byte FIELD_MARKER = 2;
|
||||
|
||||
private static Collection<JavacRef> readRefs(final DataInput in) throws IOException {
|
||||
return DataInputOutputUtil.readSeq(in, new ThrowableComputable<JavacRef, IOException>() {
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, JavacRef ref) throws IOException {
|
||||
if (ref instanceof JavacRef.JavacClass) {
|
||||
out.writeByte(CLASS_MARKER);
|
||||
out.writeBoolean(((JavacRef.JavacClass)ref).isAnonymous());
|
||||
}
|
||||
else if (ref instanceof JavacRef.JavacField) {
|
||||
out.writeByte(FIELD_MARKER);
|
||||
IOUtil.writeUTF(out, ref.getOwnerName());
|
||||
}
|
||||
else if (ref instanceof JavacRef.JavacMethod) {
|
||||
out.writeByte(METHOD_MARKER);
|
||||
IOUtil.writeUTF(out, ref.getOwnerName());
|
||||
out.write(((JavacRef.JavacMethod)ref).getParamCount());
|
||||
} else {
|
||||
throw new IllegalStateException("unknown type: " + ref.getClass());
|
||||
}
|
||||
writeModifiers(out, ref.getModifiers());
|
||||
IOUtil.writeUTF(out, ref.getName());
|
||||
public JavacRef compute() throws IOException {
|
||||
return readJavacRef(in);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void saveDefs(final DataOutput out, List<JavacDef> defs) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(out, defs, new ThrowableConsumer<JavacDef, IOException>() {
|
||||
@Override
|
||||
public JavacRef read(@NotNull DataInput in) throws IOException {
|
||||
final byte marker = in.readByte();
|
||||
switch (marker) {
|
||||
case CLASS_MARKER:
|
||||
return new JavacRef.JavacClassImpl(in.readBoolean(), readModifiers(in), IOUtil.readUTF(in));
|
||||
case METHOD_MARKER:
|
||||
return new JavacRef.JavacMethodImpl(IOUtil.readUTF(in), in.readByte(), readModifiers(in), IOUtil.readUTF(in));
|
||||
case FIELD_MARKER:
|
||||
return new JavacRef.JavacFieldImpl(IOUtil.readUTF(in), readModifiers(in), IOUtil.readUTF(in));
|
||||
default:
|
||||
throw new IllegalStateException("unknown marker " + marker);
|
||||
public void consume(JavacDef def) throws IOException {
|
||||
writeJavacDef(out, def);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static List<JavacDef> readDefs(final DataInput in) throws IOException {
|
||||
return DataInputOutputUtil.readSeq(in, new ThrowableComputable<JavacDef, IOException>() {
|
||||
@Override
|
||||
public JavacDef compute() throws IOException {
|
||||
return readJavacDef(in);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static JavacDef readJavacDef(@NotNull DataInput in) throws IOException {
|
||||
final byte marker = in.readByte();
|
||||
switch (marker) {
|
||||
case CLASS_MARKER:
|
||||
final int supersSize = in.readInt();
|
||||
JavacRef[] superClasses = new JavacRef[supersSize];
|
||||
for (int i = 0; i < supersSize; i++) {
|
||||
superClasses[i] = readJavacRef(in);
|
||||
}
|
||||
}
|
||||
return new JavacDef.JavacClassDef(readJavacRef(in), superClasses);
|
||||
case FUN_EXPR_MARKER:
|
||||
return new JavacDef.JavacFunExprDef(readJavacRef(in));
|
||||
default:
|
||||
throw new IllegalStateException("unknown marker " + marker);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeModifiers(final DataOutput output, Set<Modifier> modifiers) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(output, modifiers, new ThrowableConsumer<Modifier, IOException>() {
|
||||
@Override
|
||||
public void consume(Modifier modifier) throws IOException {
|
||||
IOUtil.writeUTF(output, modifier.name());
|
||||
}
|
||||
});
|
||||
private static void writeJavacDef(@NotNull DataOutput out, JavacDef def) throws IOException {
|
||||
if (def instanceof JavacDef.JavacClassDef) {
|
||||
out.writeByte(CLASS_MARKER);
|
||||
final JavacRef[] superClasses = ((JavacDef.JavacClassDef)def).getSuperClasses();
|
||||
out.writeInt(superClasses.length);
|
||||
for (JavacRef aClass : superClasses) {
|
||||
writeJavacRef(out, aClass);
|
||||
}
|
||||
}
|
||||
else if (def instanceof JavacDef.JavacFunExprDef) {
|
||||
out.writeByte(FUN_EXPR_MARKER);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("unknown type: " + def.getClass());
|
||||
}
|
||||
writeJavacRef(out, def.getDefinedElement());
|
||||
}
|
||||
|
||||
private Set<Modifier> readModifiers(final DataInput input) throws IOException {
|
||||
return EnumSet.copyOf(DataInputOutputUtil.readSeq(input, new ThrowableComputable<Modifier, IOException>() {
|
||||
@Override
|
||||
public Modifier compute() throws IOException {
|
||||
return Modifier.valueOf(IOUtil.readUTF(input));
|
||||
}
|
||||
}));
|
||||
private static void writeJavacRef(@NotNull DataOutput out, JavacRef ref) throws IOException {
|
||||
if (ref instanceof JavacRef.JavacClass) {
|
||||
out.writeByte(CLASS_MARKER);
|
||||
out.writeBoolean(((JavacRef.JavacClass)ref).isAnonymous());
|
||||
}
|
||||
else if (ref instanceof JavacRef.JavacField) {
|
||||
out.writeByte(FIELD_MARKER);
|
||||
out.writeUTF(ref.getOwnerName());
|
||||
}
|
||||
else if (ref instanceof JavacRef.JavacMethod) {
|
||||
out.writeByte(METHOD_MARKER);
|
||||
out.writeUTF(ref.getOwnerName());
|
||||
out.write(((JavacRef.JavacMethod)ref).getParamCount());
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("unknown type: " + ref.getClass());
|
||||
}
|
||||
writeModifiers(out, ref.getModifiers());
|
||||
out.writeUTF(ref.getName());
|
||||
}
|
||||
|
||||
private static JavacRef readJavacRef(@NotNull DataInput in) throws IOException {
|
||||
final byte marker = in.readByte();
|
||||
switch (marker) {
|
||||
case CLASS_MARKER:
|
||||
return new JavacRef.JavacClassImpl(in.readBoolean(), readModifiers(in), in.readUTF());
|
||||
case METHOD_MARKER:
|
||||
return new JavacRef.JavacMethodImpl(in.readUTF(), in.readByte(), readModifiers(in), in.readUTF());
|
||||
case FIELD_MARKER:
|
||||
return new JavacRef.JavacFieldImpl(in.readUTF(), readModifiers(in), in.readUTF());
|
||||
default:
|
||||
throw new IllegalStateException("unknown marker " + marker);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeModifiers(final DataOutput output, Set<Modifier> modifiers) throws IOException {
|
||||
DataInputOutputUtil.writeSeq(output, modifiers, new ThrowableConsumer<Modifier, IOException>() {
|
||||
@Override
|
||||
public void consume(Modifier modifier) throws IOException {
|
||||
output.writeUTF(modifier.name());
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private static Set<Modifier> readModifiers(final DataInput input) throws IOException {
|
||||
final List<Modifier> modifierList = DataInputOutputUtil.readSeq(input, new ThrowableComputable<Modifier, IOException>() {
|
||||
@Override
|
||||
public Modifier compute() throws IOException {
|
||||
return Modifier.valueOf(input.readUTF());
|
||||
}
|
||||
});
|
||||
return modifierList.isEmpty() ? Collections.<Modifier>emptySet() : EnumSet.copyOf(modifierList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import javax.lang.model.util.Elements;
|
||||
public class JavacNameTable {
|
||||
private final SLRUCache<Name, String> myParsedNameCache;
|
||||
private final Elements myElements;
|
||||
private Name myAsterisk;
|
||||
|
||||
public JavacNameTable(Elements elements) {
|
||||
myParsedNameCache = new SLRUCache<Name, String>(1000, 1000) {
|
||||
@@ -47,4 +48,12 @@ public class JavacNameTable {
|
||||
public String parseBinaryName(Element element) {
|
||||
return parseName(myElements.getBinaryName((TypeElement)element));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Name getAsterisk() {
|
||||
if (myAsterisk == null) {
|
||||
myAsterisk = myElements.getName("*");
|
||||
}
|
||||
return myAsterisk;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,17 +23,14 @@ import com.intellij.util.indexing.impl.MapIndexStorage
|
||||
import com.intellij.util.indexing.impl.MapReduceIndex
|
||||
import com.intellij.util.io.PersistentStringEnumerator
|
||||
import org.jetbrains.jps.backwardRefs.BackwardReferenceIndexWriter
|
||||
import org.jetbrains.jps.backwardRefs.NameEnumerator
|
||||
import org.jetbrains.jps.backwardRefs.CompilerBackwardReferenceIndex
|
||||
import org.jetbrains.jps.backwardRefs.LightRef
|
||||
import org.jetbrains.jps.backwardRefs.NameEnumerator
|
||||
import org.jetbrains.jps.backwardRefs.index.CompiledFileData
|
||||
import org.jetbrains.jps.backwardRefs.index.CompilerIndices
|
||||
import org.jetbrains.jps.builders.BuildResult
|
||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||
import org.jetbrains.jps.builders.TestProjectBuilderLogger
|
||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||
import org.jetbrains.jps.javac.JavaCompilerToolExtension
|
||||
import org.jetbrains.jps.javac.ast.RefCollectorCompilerToolExtension
|
||||
import java.io.File
|
||||
|
||||
abstract class ReferenceIndexTestBase : JpsBuildTestCase() {
|
||||
@@ -60,22 +57,6 @@ abstract class ReferenceIndexTestBase : JpsBuildTestCase() {
|
||||
assertIndexEquals("initialIndex.txt")
|
||||
}
|
||||
|
||||
override fun rebuildAllModules() {
|
||||
try {
|
||||
super.rebuildAllModules()
|
||||
} finally {
|
||||
(JavaCompilerToolExtension.getExtension(RefCollectorCompilerToolExtension.ID) as RefCollectorCompilerToolExtension).clearRegistrars()
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildAllModules(): BuildResult {
|
||||
try {
|
||||
return super.buildAllModules()
|
||||
} finally {
|
||||
(JavaCompilerToolExtension.getExtension(RefCollectorCompilerToolExtension.ID) as RefCollectorCompilerToolExtension).clearRegistrars()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun renameFile(fileToRename: String, newName: String) {
|
||||
rename(orCreateProjectDir.path + "/m/" + fileToRename, newName)
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ class JsonBySchemaObjectCompletionContributor extends CompletionContributor {
|
||||
// inserting longer string for proper formatting
|
||||
final String stringToInsert = ": 1";
|
||||
EditorModificationUtil.insertStringAtCaret(editor, stringToInsert, false, true, 2);
|
||||
formatInsertedString(context, project, stringToInsert.length());
|
||||
formatInsertedString(context, stringToInsert.length());
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
context.getDocument().deleteString(offset, offset + 1);
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
@@ -277,7 +277,7 @@ class JsonBySchemaObjectCompletionContributor extends CompletionContributor {
|
||||
EditorModificationUtil.insertStringAtCaret(editor, stringToInsert, false, true, 2);
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument());
|
||||
formatInsertedString(context, project, stringToInsert.length());
|
||||
formatInsertedString(context, stringToInsert.length());
|
||||
EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_ENTER);
|
||||
handler.execute(editor, editor.getCaretModel().getCurrentCaret(),
|
||||
DataManager.getInstance().getDataContext(editor.getContentComponent()));
|
||||
@@ -288,7 +288,7 @@ class JsonBySchemaObjectCompletionContributor extends CompletionContributor {
|
||||
SelectionModel model = editor.getSelectionModel();
|
||||
|
||||
EditorModificationUtil.insertStringAtCaret(editor, stringToInsert, false, true, stringToInsert.length());
|
||||
formatInsertedString(context, context.getProject(), stringToInsert.length());
|
||||
formatInsertedString(context, stringToInsert.length());
|
||||
int start = editor.getSelectionModel().getSelectionStart();
|
||||
model.setSelection(start - value.length(), start);
|
||||
AutoPopupController.getInstance(context.getProject()).autoPopupMemberLookup(context.getEditor(), null);
|
||||
@@ -297,7 +297,7 @@ class JsonBySchemaObjectCompletionContributor extends CompletionContributor {
|
||||
stringToInsert = ":[]";
|
||||
EditorModificationUtil.insertStringAtCaret(editor, stringToInsert, false, true, 2);
|
||||
|
||||
formatInsertedString(context, project, stringToInsert.length());
|
||||
formatInsertedString(context, stringToInsert.length());
|
||||
break;
|
||||
case _string:
|
||||
case _integer:
|
||||
@@ -366,14 +366,15 @@ class JsonBySchemaObjectCompletionContributor extends CompletionContributor {
|
||||
editor.getCaretModel().moveToOffset(newOffset);
|
||||
}
|
||||
|
||||
formatInsertedString(context, context.getProject(), stringToInsert.length());
|
||||
formatInsertedString(context, stringToInsert.length());
|
||||
|
||||
if (hasValues) {
|
||||
AutoPopupController.getInstance(context.getProject()).autoPopupMemberLookup(context.getEditor(), null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void formatInsertedString(InsertionContext context, Project project, int offset) {
|
||||
public static void formatInsertedString(@NotNull InsertionContext context, int offset) {
|
||||
Project project = context.getProject();
|
||||
PsiDocumentManager.getInstance(project).commitDocument(context.getDocument());
|
||||
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
|
||||
codeStyleManager.reformatText(context.getFile(), context.getStartOffset(), context.getTailOffset() + offset);
|
||||
|
||||
@@ -278,16 +278,15 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
val oldSchemes = schemes
|
||||
val schemes = oldSchemes.toMutableList()
|
||||
val newSchemesOffset = schemes.size
|
||||
if (provider != null && provider.isApplicable(fileSpec, roamingType)) {
|
||||
provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
|
||||
catchAndLog(name) {
|
||||
val scheme = loadScheme(name, input, schemes, filesToDelete)
|
||||
if (readOnly && scheme != null) {
|
||||
readOnlyExternalizableSchemes.put(scheme.name, scheme)
|
||||
}
|
||||
if (provider != null && provider.processChildren(fileSpec, roamingType, { canRead(it) }) { name, input, readOnly ->
|
||||
catchAndLog(name) {
|
||||
val scheme = loadScheme(name, input, schemes, filesToDelete)
|
||||
if (readOnly && scheme != null) {
|
||||
readOnlyExternalizableSchemes.put(scheme.name, scheme)
|
||||
}
|
||||
true
|
||||
}
|
||||
true
|
||||
}) {
|
||||
}
|
||||
else {
|
||||
ioDirectory.directoryStreamIfExists({ canRead(it.fileName.toString()) }) {
|
||||
@@ -335,7 +334,7 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
|
||||
loadSchemes()
|
||||
|
||||
(processor as? LazySchemeProcessor)?.reloaded()
|
||||
(processor as? LazySchemeProcessor)?.reloaded(this)
|
||||
}
|
||||
|
||||
private fun removeExternalizableSchemes() {
|
||||
@@ -717,14 +716,13 @@ class SchemeManagerImpl<T : Scheme, MUTABLE_SCHEME : T>(val fileSpec: String,
|
||||
}
|
||||
|
||||
private fun deleteFiles(errors: MutableList<Throwable>, filesToDelete: MutableSet<String>) {
|
||||
if (provider != null && provider.enabled) {
|
||||
if (provider != null) {
|
||||
val iterator = filesToDelete.iterator()
|
||||
for (name in iterator) {
|
||||
errors.catch {
|
||||
val spec = "$fileSpec/$name"
|
||||
if (provider.isApplicable(spec, roamingType)) {
|
||||
if (provider.delete(spec, roamingType)) {
|
||||
iterator.remove()
|
||||
provider.delete(spec, roamingType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,28 +10,25 @@ class StreamProviderWrapper : StreamProvider {
|
||||
override val enabled: Boolean
|
||||
get() = streamProvider.let { it != null && it.enabled }
|
||||
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
return enabled && streamProvider!!.isApplicable(fileSpec, roamingType)
|
||||
}
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType) = streamProvider?.isApplicable(fileSpec, roamingType) ?: false
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
return streamProvider!!.read(fileSpec, roamingType, consumer)
|
||||
}
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit) = streamProvider?.read(fileSpec, roamingType, consumer) ?: false
|
||||
|
||||
override fun processChildren(path: String,
|
||||
roamingType: RoamingType,
|
||||
filter: Function1<String, Boolean>,
|
||||
processor: Function3<String, InputStream, Boolean, Boolean>) {
|
||||
streamProvider!!.processChildren(path, roamingType, filter, processor)
|
||||
processor: Function3<String, InputStream, Boolean, Boolean>): Boolean {
|
||||
return streamProvider?.let {
|
||||
it.processChildren(path, roamingType, filter, processor)
|
||||
true
|
||||
} ?: false
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
streamProvider!!.write(fileSpec, content, size, roamingType)
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
streamProvider!!.delete(fileSpec, roamingType)
|
||||
}
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) = streamProvider?.delete(fileSpec, roamingType) ?: false
|
||||
}
|
||||
|
||||
fun StreamProvider?.getOriginalProvider() = if (this is StreamProviderWrapper) streamProvider else null
|
||||
@@ -47,25 +47,25 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
|
||||
override fun hasState(storageData: StateMap, componentName: String) = storageData.hasState(componentName)
|
||||
|
||||
override fun loadData(): StateMap {
|
||||
val element: Element?
|
||||
// we don't use local data if has stream provider
|
||||
if (provider != null && provider.isApplicable(fileSpec, roamingType)) {
|
||||
element = LOG.catchAndLog {
|
||||
loadDataFromProvider().apply { dataLoadedFromProvider(this) }
|
||||
override fun loadData() = loadElement()?.let { loadState(it) } ?: StateMap.EMPTY
|
||||
|
||||
private fun loadElement(useStreamProvider: Boolean = true): Element? {
|
||||
var element: Element? = null
|
||||
LOG.catchAndLog {
|
||||
if (!useStreamProvider || !(provider?.read(fileSpec, roamingType) {
|
||||
it?.let {
|
||||
element = loadElement(it)
|
||||
}
|
||||
} ?: false)) {
|
||||
element = loadLocalData()
|
||||
}
|
||||
}
|
||||
else {
|
||||
element = loadLocalData()
|
||||
}
|
||||
return element?.let { loadState(element) } ?: StateMap.EMPTY
|
||||
return element
|
||||
}
|
||||
|
||||
protected open fun dataLoadedFromProvider(element: Element?) {
|
||||
}
|
||||
|
||||
private fun loadDataFromProvider(): Element? = provider!!.read(fileSpec, roamingType) { it?.let(::loadElement) }
|
||||
|
||||
private fun loadState(element: Element): StateMap {
|
||||
beforeElementLoaded(element)
|
||||
return StateMap.fromMap(FileStorageCoreUtil.load(element, pathMacroSubstitutor, true))
|
||||
@@ -127,15 +127,15 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
}
|
||||
|
||||
val provider = storage.provider
|
||||
if (provider != null && provider.isApplicable(storage.fileSpec, storage.roamingType)) {
|
||||
if (element == null) {
|
||||
provider.delete(storage.fileSpec, storage.roamingType)
|
||||
}
|
||||
else {
|
||||
// we should use standard line-separator (\n) - stream provider can share file content on any OS
|
||||
provider.write(storage.fileSpec, element.toBufferExposingByteArray(), storage.roamingType)
|
||||
if (element == null) {
|
||||
if (provider == null || !provider.delete(storage.fileSpec, storage.roamingType)) {
|
||||
saveLocally(null)
|
||||
}
|
||||
}
|
||||
else if (provider != null && provider.isApplicable(storage.fileSpec, storage.roamingType)) {
|
||||
// we should use standard line-separator (\n) - stream provider can share file content on any OS
|
||||
provider.write(storage.fileSpec, element.toBufferExposingByteArray(), storage.roamingType)
|
||||
}
|
||||
else {
|
||||
saveLocally(element)
|
||||
}
|
||||
@@ -163,14 +163,14 @@ abstract class XmlElementStorage protected constructor(val fileSpec: String,
|
||||
updatedFrom(changedComponentNames, deleted, true)
|
||||
}
|
||||
|
||||
fun updatedFrom(changedComponentNames: MutableSet<String>, deleted: Boolean, streamProvider: Boolean) {
|
||||
fun updatedFrom(changedComponentNames: MutableSet<String>, deleted: Boolean, useStreamProvider: Boolean) {
|
||||
if (roamingType == RoamingType.DISABLED) {
|
||||
// storage roaming was changed to DISABLED, but settings repository has old state
|
||||
return
|
||||
}
|
||||
|
||||
LOG.catchAndLog {
|
||||
val newElement = if (deleted) null else if (streamProvider) loadDataFromProvider() else loadLocalData()
|
||||
val newElement = if (deleted) null else loadElement(useStreamProvider)
|
||||
val states = storageDataRef.get()
|
||||
if (newElement == null) {
|
||||
// if data was loaded, mark as changed all loaded components
|
||||
|
||||
@@ -323,7 +323,8 @@ internal class ApplicationStoreTest {
|
||||
private fun writeConfig(fileName: String, @Language("XML") data: String) = testAppConfig.writeChild(fileName, data)
|
||||
|
||||
private class MyStreamProvider : StreamProvider {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (String) -> Boolean, processor: (String, InputStream, Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (String) -> Boolean, processor: (String, InputStream, Boolean) -> Boolean): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
val data: MutableMap<RoamingType, MutableMap<String, String>> = THashMap()
|
||||
@@ -341,13 +342,15 @@ internal class ApplicationStoreTest {
|
||||
return map
|
||||
}
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
val data = getMap(roamingType).get(fileSpec)
|
||||
return data?.let { ByteArrayInputStream(it.toByteArray()) }.let(consumer)
|
||||
data?.let { ByteArrayInputStream(it.toByteArray()) }.let(consumer)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
data[roamingType]?.remove(fileSpec)
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
data.get(roamingType)?.remove(fileSpec)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl
|
||||
import com.intellij.openapi.components.stateStore
|
||||
import com.intellij.testFramework.ProjectRule
|
||||
import com.intellij.testFramework.runInEdtAndWait
|
||||
import com.intellij.util.io.delete
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Test
|
||||
import java.nio.file.Paths
|
||||
|
||||
class DoNotSaveDefaultsTest {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val projectRule = ProjectRule()
|
||||
|
||||
init {
|
||||
Paths.get(PathManager.getConfigPath()).delete()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test() {
|
||||
val app = ApplicationManager.getApplication() as ApplicationImpl
|
||||
val directory = app.stateStore.stateStorageManager.expandMacros(APP_CONFIG)
|
||||
val dirPath = Paths.get(directory)
|
||||
try {
|
||||
app.doNotSave(false)
|
||||
runInEdtAndWait {
|
||||
app.saveAll()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
app.doNotSave(true)
|
||||
}
|
||||
|
||||
println(directory)
|
||||
println(printDirectoryTree(dirPath.toFile()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import java.io.File
|
||||
|
||||
fun printDirectoryTree(folder: File): String {
|
||||
if (!folder.isDirectory) {
|
||||
throw IllegalArgumentException("folder is not a Directory")
|
||||
}
|
||||
val indent = 0
|
||||
val sb = StringBuilder()
|
||||
printDirectoryTree(folder, indent, sb)
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun printDirectoryTree(folder: File, indent: Int, sb: StringBuilder) {
|
||||
if (!folder.isDirectory) {
|
||||
throw IllegalArgumentException("folder is not a Directory")
|
||||
}
|
||||
getIndentString(indent, sb)
|
||||
sb.append("\u251c\u2500\u2500")
|
||||
sb.append(folder.name)
|
||||
sb.append("/")
|
||||
sb.append("\n")
|
||||
for (file in folder.listFiles()!!) {
|
||||
if (file.isDirectory) {
|
||||
printDirectoryTree(file, indent + 1, sb)
|
||||
}
|
||||
else {
|
||||
printFile(file, indent + 1, sb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun printFile(file: File, indent: Int, sb: StringBuilder) {
|
||||
getIndentString(indent, sb)
|
||||
sb.append("\u251c\u2500\u2500")
|
||||
sb.append(file.name)
|
||||
sb.append("\n")
|
||||
}
|
||||
|
||||
private fun getIndentString(indent: Int, sb: StringBuilder) {
|
||||
for (i in 0..indent - 1) {
|
||||
sb.append(" ")
|
||||
}
|
||||
}
|
||||
@@ -11,17 +11,18 @@ class MockStreamProvider(private val dir: Path) : StreamProvider {
|
||||
dir.resolve(fileSpec).write(content, 0, size)
|
||||
}
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
val file = dir.resolve(fileSpec)
|
||||
try {
|
||||
return file.inputStream().use(consumer)
|
||||
file.inputStream().use(consumer)
|
||||
}
|
||||
catch (e: NoSuchFileException) {
|
||||
return consumer(null)
|
||||
consumer(null)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean {
|
||||
dir.resolve(path).directoryStreamIfExists({ filter(it.fileName.toString()) }) {
|
||||
for (file in it) {
|
||||
val attributes = file.basicAttributesIfExists()
|
||||
@@ -40,9 +41,12 @@ class MockStreamProvider(private val dir: Path) : StreamProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
dir.resolve(fileSpec).delete()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,7 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
};
|
||||
|
||||
myLeftPanel = new NonOpaquePanel(new BorderLayout());
|
||||
myLeftPanel.setBorder(JBUI.Borders.emptyLeft(6));
|
||||
myLeftPanel.add(mySearchFieldWrapper, BorderLayout.NORTH);
|
||||
myLeftPanel.add(myReplaceFieldWrapper, BorderLayout.SOUTH);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.find.editorHeaderActions.Utils;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
|
||||
import com.intellij.ide.ui.laf.intellij.MacIntelliJIconCache;
|
||||
import com.intellij.ide.ui.laf.intellij.MacIntelliJTextFieldUI;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
@@ -27,6 +28,7 @@ import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.actionSystem.impl.InplaceActionButtonLook;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -37,6 +39,7 @@ import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.paint.RectanglePainter;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.JBDimension;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
@@ -52,7 +55,6 @@ import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
@@ -64,7 +66,8 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
private ActionButton myNewLineButton;
|
||||
private ActionButton myClearButton;
|
||||
private JBScrollPane myScrollPane;
|
||||
private ActionButton myHistoryPopupButton;
|
||||
private final ActionButton myHistoryPopupButton;
|
||||
private final LafHelper myHelper;
|
||||
|
||||
public SearchTextArea(boolean search) {
|
||||
this(new JTextArea(), search, false);
|
||||
@@ -103,8 +106,8 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
public Insets getBorderInsets(Component c) {
|
||||
int bottom = (StringUtil.getLineBreakCount(myTextArea.getText()) > 0) ? 2 : UIUtil.isUnderDarcula() ? 1 : 0;
|
||||
int top = myTextArea.getFontMetrics(myTextArea.getFont()).getHeight() <= 16 ? 2 : 1;
|
||||
if (JBUI.isHiDPI()) bottom = 2;
|
||||
if (JBUI.isHiDPI()) top = 2;
|
||||
if (JBUI.isHiDPI(c)) bottom = 2;
|
||||
if (JBUI.isHiDPI(c)) top = 2;
|
||||
return new JBInsets(top, 0, bottom, 0);
|
||||
}
|
||||
|
||||
@@ -122,6 +125,8 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
myInfoLabel = new JBLabel(UIUtil.ComponentStyle.SMALL);
|
||||
myInfoLabel.setForeground(JBColor.GRAY);
|
||||
|
||||
myHelper = createHelper();
|
||||
|
||||
myHistoryPopupButton = createButton(new ShowHistoryAction(search));
|
||||
myClearButton = createButton(new ClearAction());
|
||||
myNewLineButton = createButton(new NewLineAction());
|
||||
@@ -131,20 +136,17 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
}
|
||||
|
||||
protected void updateLayout() {
|
||||
int height = UIUtil.getLineHeight(myTextArea);
|
||||
Insets insets = myTextArea.getInsets();
|
||||
int extraGap = Math.max(JBUI.isHiDPI() ? 0 : 1, (height + insets.top + insets.bottom - JBUI.scale(16)) / 2);
|
||||
setBorder(new EmptyBorder(3 + Math.max(0, JBUI.scale(16) - height) / 2, 6, 3, 4));//In case of small fonts we shouldn't align to top
|
||||
setLayout(new MigLayout("flowx, ins 0, gapx " + JBUI.scale(4)));
|
||||
setBorder(myHelper.getBorder());
|
||||
setLayout(new MigLayout(myHelper.getLayoutConstraints()));
|
||||
removeAll();
|
||||
add(myHistoryPopupButton, "ay top, gaptop " + extraGap +", gapleft" + (JBUI.isHiDPI() ? 4 : 0));
|
||||
add(myHistoryPopupButton, myHelper.getHistoryButtonConstraints());
|
||||
add(myScrollPane, "ay top, growx, pushx");
|
||||
//TODO combine icons/info modes
|
||||
if (myInfoMode) {
|
||||
add(myInfoLabel);
|
||||
}
|
||||
else {
|
||||
add(myIconsPanel, "gaptop " + extraGap + ",ay top, gapright " + extraGap/2);
|
||||
add(myIconsPanel, myHelper.getIconsPanelConstraints());
|
||||
updateIconsLayout();
|
||||
}
|
||||
}
|
||||
@@ -181,7 +183,7 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
if (multiline && showNewLine) {
|
||||
myIconsPanel.add(myNewLineButton);
|
||||
}
|
||||
myIconsPanel.setBorder(JBUI.Borders.emptyBottom(rows == 2 ? 3 : 0));
|
||||
myIconsPanel.setBorder(myHelper.getIconsPanelBorder(rows));
|
||||
myScrollPane.revalidate();
|
||||
doLayout();
|
||||
}
|
||||
@@ -228,38 +230,10 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
@Override
|
||||
public void paint(Graphics graphics) {
|
||||
Graphics2D g = (Graphics2D)graphics.create();
|
||||
boolean hasFocus = myTextArea.hasFocus();
|
||||
try {
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||
Rectangle r = new Rectangle(getSize());
|
||||
r.height = Math.max(r.height, myScrollPane.getHeight() + getInsets().top + getInsets().bottom);
|
||||
if (myIconsPanel.getParent() != null) {
|
||||
r.height = Math.max(r.height, myIconsPanel.getHeight() + getInsets().top + getInsets().bottom);
|
||||
}
|
||||
if (r.height % 2 == 1) r.height--;
|
||||
int arcSize = Math.min(Math.max(25, myTextArea.getFontMetrics(myTextArea.getFont()).getHeight() * 3 / 2), r.height - 1);
|
||||
if (JBUI.isHiDPI()) arcSize = JBUI.scale(21);
|
||||
Color borderColor = myTextArea.isEnabled() ? enabledBorderColor : disabledBorderColor;
|
||||
if (SystemInfo.isMac && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderAquaLookAndFeel())) {
|
||||
g.setColor(borderColor);
|
||||
MacIntelliJTextFieldUI.paintAquaSearchFocusRing(g, r, myTextArea);
|
||||
}
|
||||
else {
|
||||
JBInsets.removeFrom(r, new JBInsets(3, 3, 3, 3));
|
||||
if (hasFocus && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) {
|
||||
DarculaUIUtil.paintSearchFocusRing(g, r, myTextArea, arcSize);
|
||||
}
|
||||
else {
|
||||
Shape shape = UIUtil.isUnderWindowsLookAndFeel()
|
||||
? new Rectangle(r.x, r.y, r.width, r.height)
|
||||
: new RoundRectangle2D.Double(r.x, r.y, r.width, r.height, arcSize - JBUI.scale(5), arcSize - JBUI.scale(5));
|
||||
g.setColor(myTextArea.getBackground());
|
||||
g.fill(shape);
|
||||
g.setColor(borderColor);
|
||||
g.draw(shape);
|
||||
}
|
||||
}
|
||||
myHelper.paint(g);
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
@@ -284,7 +258,7 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
public ShowHistoryAction(boolean search) {
|
||||
super((search ? "Search" : "Replace") + " History",
|
||||
(search ? "Search" : "Replace") + " history",
|
||||
MacIntelliJIconCache.getIcon("searchFieldWithHistory"));
|
||||
myHelper.getShowHistoryIcon());
|
||||
|
||||
myShowSearchHistory = search;
|
||||
|
||||
@@ -321,7 +295,7 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
|
||||
private class ClearAction extends DumbAwareAction {
|
||||
public ClearAction() {
|
||||
super(null, null, AllIcons.Actions.Clear);
|
||||
super(null, null, myHelper.getClearIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,7 +306,8 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
|
||||
private class NewLineAction extends DumbAwareAction {
|
||||
public NewLineAction() {
|
||||
super(null, "New line (" + KeymapUtil.getKeystrokeText(SearchReplaceComponent.NEW_LINE_KEYSTROKE) + ")", AllIcons.Actions.SearchNewLine);
|
||||
super(null, "New line (" + KeymapUtil.getKeystrokeText(SearchReplaceComponent.NEW_LINE_KEYSTROKE) + ")",
|
||||
AllIcons.Actions.SearchNewLine);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -340,4 +315,152 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
new DefaultEditorKit.InsertBreakAction().actionPerformed(new ActionEvent(myTextArea, 0, "action"));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LafHelper createHelper() {
|
||||
return SystemInfo.isMac ? new MacLafHelper() : new DefaultLafHelper();
|
||||
}
|
||||
|
||||
private static abstract class LafHelper {
|
||||
abstract Border getBorder();
|
||||
|
||||
abstract String getLayoutConstraints();
|
||||
|
||||
abstract String getHistoryButtonConstraints();
|
||||
|
||||
abstract String getIconsPanelConstraints();
|
||||
|
||||
abstract Border getIconsPanelBorder(int rows);
|
||||
|
||||
abstract Icon getShowHistoryIcon();
|
||||
|
||||
abstract Icon getClearIcon();
|
||||
|
||||
abstract void paint(Graphics2D g);
|
||||
}
|
||||
|
||||
private class MacLafHelper extends LafHelper {
|
||||
@Override
|
||||
Border getBorder() {
|
||||
return new EmptyBorder(3 + Math.max(0, JBUI.scale(16) - UIUtil.getLineHeight(myTextArea)) / 2, 6, 3, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getLayoutConstraints() {
|
||||
return "flowx, ins 0, gapx " + JBUI.scale(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getHistoryButtonConstraints() {
|
||||
int extraGap = getExtraGap();
|
||||
return "ay top, gaptop " + extraGap + ", gapleft" + (JBUI.isHiDPI(myTextArea) ? 4 : 0);
|
||||
}
|
||||
|
||||
private int getExtraGap() {
|
||||
int height = UIUtil.getLineHeight(myTextArea);
|
||||
Insets insets = myTextArea.getInsets();
|
||||
return Math.max(JBUI.isHiDPI(myTextArea) ? 0 : 1, (height + insets.top + insets.bottom - JBUI.scale(16)) / 2);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
String getIconsPanelConstraints() {
|
||||
int extraGap = getExtraGap();
|
||||
return "gaptop " + extraGap + ",ay top, gapright " + extraGap / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
Border getIconsPanelBorder(int rows) {
|
||||
return JBUI.Borders.emptyBottom(rows == 2 ? 3 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
Icon getShowHistoryIcon() {
|
||||
return MacIntelliJIconCache.getIcon("searchFieldWithHistory");
|
||||
}
|
||||
|
||||
@Override
|
||||
Icon getClearIcon() {
|
||||
return AllIcons.Actions.Clear;
|
||||
}
|
||||
|
||||
@Override
|
||||
void paint(Graphics2D g) {
|
||||
Rectangle r = new Rectangle(getSize());
|
||||
int h = myIconsPanel.getParent() != null ? Math.max(myIconsPanel.getHeight(), myScrollPane.getHeight()) : myScrollPane.getHeight();
|
||||
r.height = Math.max(r.height, h + getInsets().top + getInsets().bottom);
|
||||
if (r.height % 2 == 1) r.height--;
|
||||
g.setColor(myTextArea.isEnabled() ? enabledBorderColor : disabledBorderColor);
|
||||
MacIntelliJTextFieldUI.paintAquaSearchFocusRing(g, r, myTextArea);
|
||||
}
|
||||
}
|
||||
|
||||
private class DefaultLafHelper extends LafHelper {
|
||||
@Override
|
||||
Border getBorder() {
|
||||
return JBUI.Borders.empty(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getLayoutConstraints() {
|
||||
return "flowx, ins 2 " + JBUI.scale(4) + " 2 " + (3 + JBUI.scale(1)) + ", gapx " + JBUI.scale(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getHistoryButtonConstraints() {
|
||||
return "ay top, gaptop " + JBUI.scale(getIconTopGap());//Double scaling inside but it looks not bad
|
||||
}
|
||||
|
||||
private int getIconTopGap() {
|
||||
return Math.max(2, (UIUtil.getLineHeight(myTextArea) + myTextArea.getInsets().top + myTextArea.getInsets().bottom - JBUI.scale(16)) / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getIconsPanelConstraints() {
|
||||
return "gaptop " + getIconTopGap() + ",ay top";
|
||||
}
|
||||
|
||||
@Override
|
||||
Border getIconsPanelBorder(int rows) {
|
||||
return JBUI.Borders.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
Icon getShowHistoryIcon() {
|
||||
Icon searchIcon = UIManager.getIcon("TextField.darcula.searchWithHistory.icon");
|
||||
if (searchIcon == null) {
|
||||
searchIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/searchWithHistory.png", DarculaTextFieldUI.class, true);
|
||||
}
|
||||
return searchIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
Icon getClearIcon() {
|
||||
Icon clearIcon = UIManager.getIcon("TextField.darcula.clear.icon");
|
||||
if (clearIcon == null) {
|
||||
clearIcon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/clear.png", DarculaTextFieldUI.class, true);
|
||||
}
|
||||
return clearIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
void paint(Graphics2D g) {
|
||||
Rectangle r = new Rectangle(getSize());
|
||||
JBInsets.removeFrom(r, getInsets());
|
||||
if (r.height % 2 == 1) r.height++;
|
||||
int arcSize = JBUI.scale(26);
|
||||
|
||||
JBInsets.removeFrom(r, new JBInsets(1, 1, 1, 1));
|
||||
if (myTextArea.hasFocus()) {
|
||||
g.setColor(myTextArea.getBackground());
|
||||
RectanglePainter.FILL.paint(g, r.x, r.y, r.width, r.height, arcSize);
|
||||
DarculaUIUtil.paintSearchFocusRing(g, r, myTextArea, arcSize);
|
||||
}
|
||||
else {
|
||||
arcSize -= JBUI.scale(5);
|
||||
RectanglePainter
|
||||
.paint(g, r.x, r.y, r.width, r.height, arcSize, myTextArea.getBackground(), myTextArea.isEnabled() ? Gray._100 : Gray._83);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
package com.intellij.openapi.editor.actions;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageExtension;
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.parser.GeneratedParserUtilBase;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -130,6 +130,24 @@ public class FlipCommaIntention implements IntentionAction {
|
||||
|
||||
@Nullable
|
||||
private static PsiElement smartAdvance(PsiElement element, boolean fwd) {
|
||||
return getSiblings(element, fwd).filter(e -> isFlippable(e)).first();
|
||||
final PsiElement candidate = getSiblings(element, fwd).filter(e -> isFlippable(e)).first();
|
||||
if (candidate != null && isBrace(candidate)) return null;
|
||||
return candidate;
|
||||
}
|
||||
|
||||
private static boolean isBrace(@NotNull PsiElement candidate) {
|
||||
final ASTNode node = candidate.getNode();
|
||||
if (node != null && node.getFirstChildNode() == null) {
|
||||
final PairedBraceMatcher braceMatcher = LanguageBraceMatching.INSTANCE.forLanguage(candidate.getLanguage());
|
||||
if (braceMatcher != null) {
|
||||
final IElementType elementType = node.getElementType();
|
||||
for (BracePair pair : braceMatcher.getPairs()) {
|
||||
if (elementType == pair.getLeftBraceType() || elementType == pair.getRightBraceType()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,6 +36,7 @@ import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -233,8 +234,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
|
||||
public boolean beforeOkAction() {
|
||||
try {
|
||||
PluginManager.saveDisabledPlugins(myPluginGroups.getDisabledPluginIds(), false);
|
||||
IdeInitialConfigButtonUsages.setPredefinedDisabledPlugins(new com.intellij.util.containers.HashSet<>(myPluginGroups.getDisabledPluginIds())/*
|
||||
myPluginGroups.getTree().values().stream().flatMap(pair -> pair.getSecond().stream()).collect(Collectors.toSet())*/);
|
||||
IdeInitialConfigButtonUsages.setPredefinedDisabledPlugins(new HashSet<>(myPluginGroups.getDisabledPluginIds()));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
|
||||
+2
-2
@@ -223,7 +223,7 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI {
|
||||
if (c.hasFocus()) {
|
||||
Color graphiteColor = new Color(0x6f6f72);
|
||||
Color blueColor = ColorUtil.brighter(new Color(0x006de2), 3);
|
||||
g.setColor(ColorUtil.withAlpha(IntelliJLaf.isGraphite() ? graphiteColor : blueColor, .3));
|
||||
g.setColor(ColorUtil.withAlpha(IntelliJLaf.isGraphite() ? graphiteColor : blueColor, .35));
|
||||
Area area = new Area(getShape(r, 7, false));
|
||||
area.subtract(new Area(getShape(r, 3.5, true)));
|
||||
g.fill(area);
|
||||
@@ -232,7 +232,7 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI {
|
||||
}
|
||||
|
||||
private static RoundRectangle2D.Double getShape(Rectangle r, double radius, boolean inner) {
|
||||
double max_radius = 7;
|
||||
double max_radius = 6;
|
||||
radius = Math.min(max_radius, Math.max(0, radius));
|
||||
double inset = max_radius - radius;
|
||||
double indent = inner ? 0.5 : 0;
|
||||
|
||||
+18
-10
@@ -31,19 +31,27 @@ public final class IdeInitialConfigButtonUsages {
|
||||
|
||||
private static volatile Set<String> ourPredefinedDisabledPlugins = ALL_PLUGINS_SELECTED;
|
||||
|
||||
private static volatile Set<String> ourDownloadedPlugins = Collections.emptySet();
|
||||
private static Set<String> ourDownloadedPlugins = Collections.emptySet();
|
||||
|
||||
public static ConfigImport getConfigImport() {
|
||||
return ourConfigImport;
|
||||
}
|
||||
|
||||
public static void setConfigImport(JRadioButton ...buttons) {
|
||||
if (buttons.length < ConfigImport.values().length) {
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
if (buttons[i] != null && buttons[i].isSelected()) {
|
||||
ourConfigImport = ConfigImport.values()[i];
|
||||
}
|
||||
}
|
||||
public static void setConfigImport(JRadioButton myRbDoNotImport,
|
||||
JRadioButton myRbImport,
|
||||
JRadioButton myRbImportAuto,
|
||||
JRadioButton myCustomButton) {
|
||||
if (myRbDoNotImport != null && myRbDoNotImport.isSelected()) {
|
||||
ourConfigImport = ConfigImport.DO_NOT_IMPORT;
|
||||
}
|
||||
else if (myRbImport != null && myRbImport.isSelected()) {
|
||||
ourConfigImport = ConfigImport.IMPORT_PATH;
|
||||
}
|
||||
else if (myRbImportAuto != null && myRbImportAuto.isSelected()) {
|
||||
ourConfigImport = ConfigImport.IMPORT_AUTO;
|
||||
}
|
||||
else if (myCustomButton != null && myCustomButton.isSelected()) {
|
||||
ourConfigImport = ConfigImport.IMPORT_CUSTOM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,11 +74,11 @@ public final class IdeInitialConfigButtonUsages {
|
||||
ourPredefinedDisabledPlugins = predefinedDisabledPlugins;
|
||||
}
|
||||
|
||||
public static Set<String> getDownloadedPlugins() {
|
||||
public synchronized static Set<String> getDownloadedPlugins() {
|
||||
return ourDownloadedPlugins;
|
||||
}
|
||||
|
||||
public static void addDownloadedPlugin(String pluginId) {
|
||||
public synchronized static void addDownloadedPlugin(String pluginId) {
|
||||
if (ourDownloadedPlugins.isEmpty()) {
|
||||
ourDownloadedPlugins = new HashSet<>();
|
||||
}
|
||||
|
||||
+7
-3
@@ -40,6 +40,7 @@ import com.intellij.openapi.options.SchemeState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.AppUIUtil;
|
||||
import com.intellij.util.ComponentTreeEventDispatcher;
|
||||
import com.intellij.util.JdomKt;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
@@ -130,9 +131,12 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloaded() {
|
||||
initEditableDefaultSchemesCopies();
|
||||
initEditableBundledSchemesCopies();
|
||||
public void reloaded(@NotNull SchemeManager<EditorColorsScheme> schemeManager) {
|
||||
// todo is EDT really required (develar: for now it will be better just to use invokeOnEdt)
|
||||
AppUIUtil.invokeOnEdt(() -> {
|
||||
initEditableDefaultSchemesCopies();
|
||||
initEditableBundledSchemesCopies();
|
||||
});
|
||||
}
|
||||
}
|
||||
mySchemeManager = schemeManagerFactory.create(FILE_SPEC, new EditorColorSchemeProcessor());
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.options.SchemeManagerFactory
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.Conditions
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.ui.AppUIUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.containers.SmartHashSet
|
||||
import gnu.trove.THashMap
|
||||
@@ -59,6 +60,15 @@ class KeymapManagerImpl(defaultKeymap: DefaultKeymap, factory: SchemeManagerFact
|
||||
listener.activeKeymapChanged(newScheme)
|
||||
}
|
||||
}
|
||||
|
||||
override fun reloaded(schemeManager: SchemeManager<Keymap>) {
|
||||
if (schemeManager.currentScheme == null) {
|
||||
// listeners expect that event will be fired in EDT
|
||||
AppUIUtil.invokeOnEdt {
|
||||
schemeManager.setCurrentSchemeName(defaultKeymap.defaultKeymapName, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
val systemDefaultKeymap = if (WelcomeWizardUtil.getWizardMacKeymap() == null) defaultKeymap.defaultKeymapName else WelcomeWizardUtil.getWizardMacKeymap()
|
||||
|
||||
@@ -26,9 +26,7 @@ import javax.swing.ButtonGroup
|
||||
import javax.swing.JLabel
|
||||
|
||||
class LayoutBuilder(val `$`: LayoutBuilderImpl, val buttonGroup: ButtonGroup? = null) {
|
||||
inline fun row(label: String, init: Row.() -> Unit) {
|
||||
row(label = Label(label), init = init)
|
||||
}
|
||||
inline fun row(label: String, init: Row.() -> Unit) = row(label = Label(label), init = init)
|
||||
|
||||
inline fun row(label: JLabel? = null, separated: Boolean = false, init: Row.() -> Unit): Row {
|
||||
val row = `$`.newRow(label, buttonGroup, separated)
|
||||
|
||||
@@ -81,6 +81,7 @@ internal class MigLayoutBuilder : LayoutBuilderImpl {
|
||||
}
|
||||
|
||||
lc.noVisualPadding()
|
||||
lc.hideMode = 3
|
||||
|
||||
container.layout = MigLayout(lc)
|
||||
|
||||
@@ -209,6 +210,19 @@ private class MigLayoutRow(private val componentConstraints: MutableMap<Componen
|
||||
}
|
||||
}
|
||||
|
||||
override var visible: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
for (c in components) {
|
||||
c.isVisible = value
|
||||
}
|
||||
}
|
||||
|
||||
override var subRowsEnabled: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
@@ -220,6 +234,17 @@ private class MigLayoutRow(private val componentConstraints: MutableMap<Componen
|
||||
_subRows?.forEach { it.enabled = value }
|
||||
}
|
||||
|
||||
override var subRowsVisible: Boolean = true
|
||||
get() = field
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
_subRows?.forEach { it.visible = value }
|
||||
}
|
||||
|
||||
override operator fun JComponent.invoke(vararg constraints: CCFlags, gapLeft: Int, growPolicy: GrowPolicy?) {
|
||||
addComponent(this, constraints, gapLeft = gapLeft, growPolicy = growPolicy)
|
||||
}
|
||||
|
||||
@@ -45,8 +45,12 @@ import javax.swing.JLabel
|
||||
abstract class Row() {
|
||||
abstract var enabled: Boolean
|
||||
|
||||
abstract var visible: Boolean
|
||||
|
||||
abstract var subRowsEnabled: Boolean
|
||||
|
||||
abstract var subRowsVisible: Boolean
|
||||
|
||||
abstract val subRows: List<Row>
|
||||
|
||||
protected abstract val builder: LayoutBuilderImpl
|
||||
|
||||
@@ -24,6 +24,9 @@ interface StreamProvider {
|
||||
val enabled: Boolean
|
||||
get() = true
|
||||
|
||||
/**
|
||||
* Called only on `write`
|
||||
*/
|
||||
fun isApplicable(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT) = true
|
||||
|
||||
/**
|
||||
@@ -33,14 +36,22 @@ interface StreamProvider {
|
||||
*/
|
||||
fun write(fileSpec: String, content: ByteArray, size: Int = content.size, roamingType: RoamingType = RoamingType.DEFAULT)
|
||||
|
||||
fun <R> read(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, consumer: (InputStream?) -> R): R
|
||||
/**
|
||||
* `true` if provider is applicable for file.
|
||||
*/
|
||||
fun read(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, consumer: (InputStream?) -> Unit): Boolean
|
||||
|
||||
fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean)
|
||||
/**
|
||||
* `true` if provider is fully responsible and local sources must be not used.
|
||||
*/
|
||||
fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean
|
||||
|
||||
/**
|
||||
* Delete file or directory
|
||||
*
|
||||
* `true` if provider is fully responsible and local sources must be not used.
|
||||
*/
|
||||
fun delete(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT)
|
||||
fun delete(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT): Boolean
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
+7
-5
@@ -27,24 +27,26 @@ import java.io.InputStream
|
||||
class SchemeManagerIprProvider(private val subStateTagName: String) : StreamProvider {
|
||||
private val nameToData = ContainerUtil.newConcurrentMap<String, ByteArray>()
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R {
|
||||
val name = PathUtilRt.getFileName(fileSpec)
|
||||
return nameToData.get(name)?.let(ByteArray::inputStream).let { consumer(it) }
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
nameToData.get(PathUtilRt.getFileName(fileSpec))?.let(ByteArray::inputStream).let { consumer(it) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
nameToData.remove(PathUtilRt.getFileName(fileSpec))
|
||||
return true
|
||||
}
|
||||
|
||||
override fun processChildren(path: String,
|
||||
roamingType: RoamingType,
|
||||
filter: (String) -> Boolean,
|
||||
processor: (String, InputStream, Boolean) -> Boolean) {
|
||||
processor: (String, InputStream, Boolean) -> Boolean): Boolean {
|
||||
for ((name, data) in nameToData) {
|
||||
if (filter(name) && !data.inputStream().use { processor(name, it, false) }) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
|
||||
@@ -66,7 +66,10 @@ abstract class LazySchemeProcessor<SCHEME : Scheme, MUTABLE_SCHEME : SCHEME>(pri
|
||||
|
||||
open fun isSchemeEqualToBundled(scheme: MUTABLE_SCHEME) = false
|
||||
|
||||
open fun reloaded() {
|
||||
/**
|
||||
* May be called from any thread - EDT is not guaranteed.
|
||||
*/
|
||||
open fun reloaded(schemeManager: SchemeManager<SCHEME>) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ open class ApplicationRule : ExternalResource() {
|
||||
/**
|
||||
* Project created on request, so, could be used as a bare (only application).
|
||||
*/
|
||||
class ProjectRule() : ApplicationRule() {
|
||||
class ProjectRule : ApplicationRule() {
|
||||
companion object {
|
||||
private var sharedProject: ProjectEx? = null
|
||||
private val projectOpened = AtomicBoolean()
|
||||
@@ -242,7 +242,7 @@ fun Project.use(task: (Project) -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
class DisposeNonLightProjectsRule() : ExternalResource() {
|
||||
class DisposeNonLightProjectsRule : ExternalResource() {
|
||||
override fun after() {
|
||||
val projectManager = if (ApplicationManager.getApplication().isDisposed) null else ProjectManager.getInstance() as ProjectManagerImpl
|
||||
projectManager?.openProjects?.forEachGuaranteed {
|
||||
|
||||
@@ -36,8 +36,6 @@ import java.awt.*;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -458,6 +456,21 @@ public class JBUI {
|
||||
return isHiDPI((GraphicsDevice)null, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent of {@link #isHiDPI(Graphics2D, ScaleType)} called for the graphics of specified component.
|
||||
*
|
||||
* @see #isHiDPI(Graphics2D, ScaleType)
|
||||
* @param component if it's <code>null</code> the graphics of the default screen device will be used
|
||||
*/
|
||||
public static boolean isHiDPI(@Nullable Component component) {
|
||||
Graphics graphics = component != null? component.getGraphics() : null;
|
||||
try {
|
||||
return isHiDPI((Graphics2D)graphics, ScaleType.USR);
|
||||
} finally {
|
||||
if (graphics != null) graphics.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Fonts {
|
||||
public static JBFont label() {
|
||||
return JBFont.create(UIManager.getFont("Label.font"), false);
|
||||
|
||||
+2
@@ -73,6 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.GrScopeProcessorWithHints;
|
||||
import org.jetbrains.plugins.groovy.transformations.impl.GroovyObjectTransformationSupport;
|
||||
import org.jetbrains.plugins.groovy.util.LightCacheKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -336,6 +337,7 @@ public class GrUnresolvedAccessChecker {
|
||||
}
|
||||
|
||||
private static boolean isNotFromGroovyObject(@NotNull PsiMethod found) {
|
||||
if (GroovyObjectTransformationSupport.isGroovyObjectSupportMethod(found)) return false;
|
||||
PsiClass aClass = found.getContainingClass();
|
||||
if (aClass == null) return false;
|
||||
String qname = aClass.getQualifiedName();
|
||||
|
||||
+1
-1
@@ -882,7 +882,7 @@ public class TypesUtil {
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass resolved = ((PsiClassType)type).resolve();
|
||||
if (resolved instanceof PsiAnonymousClass) {
|
||||
return getQualifiedName(((PsiAnonymousClass)resolved).getBaseClassType());
|
||||
return "anonymous " + getQualifiedName(((PsiAnonymousClass)resolved).getBaseClassType());
|
||||
}
|
||||
if (resolved != null) {
|
||||
return resolved.getQualifiedName();
|
||||
|
||||
+16
-29
@@ -29,14 +29,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClassReferenceType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrStubElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
@@ -144,11 +140,7 @@ public class GrAnonymousClassDefinitionImpl extends GrTypeDefinitionImpl impleme
|
||||
public PsiClass getSuperClass() {
|
||||
final PsiClass psiClass = getBaseClass();
|
||||
if (psiClass != null && !psiClass.isInterface()) return psiClass;
|
||||
return GroovyPsiManager.getInstance(getProject()).findClassWithCache(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT, getResolveScope());
|
||||
}
|
||||
|
||||
private PsiClassType createTypeByName(String className) {
|
||||
return TypesUtil.createTypeByFQClassName(className, this);
|
||||
return JavaPsiFacade.getInstance(getProject()).findClass(CommonClassNames.JAVA_LANG_OBJECT, getResolveScope());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,22 +151,7 @@ public class GrAnonymousClassDefinitionImpl extends GrTypeDefinitionImpl impleme
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getExtendsListTypes(boolean includeSynthetic) {
|
||||
final PsiClass baseClass = getBaseClass();
|
||||
|
||||
if (baseClass != null) {
|
||||
if (baseClass.isInterface()) {
|
||||
return new PsiClassType[]{createTypeByName(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT)};
|
||||
}
|
||||
else {
|
||||
if (baseClass instanceof GrTypeDefinition) {
|
||||
return new PsiClassType[]{getBaseClassType()};
|
||||
}
|
||||
else {
|
||||
return new PsiClassType[]{getBaseClassType(), createTypeByName(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT)};
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.getExtendsListTypes(includeSynthetic);
|
||||
return PsiClassType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -190,11 +167,21 @@ public class GrAnonymousClassDefinitionImpl extends GrTypeDefinitionImpl impleme
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getImplementsListTypes(boolean includeSynthetic) {
|
||||
final PsiClass baseClass = getBaseClass();
|
||||
if (baseClass != null && baseClass.isInterface()) {
|
||||
return new PsiClassType[]{getBaseClassType(), createTypeByName(GroovyCommonClassNames.GROOVY_OBJECT)};
|
||||
return PsiClassType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClassType[] getSuperTypes(boolean includeSynthetic) {
|
||||
PsiClassType baseClassType = getBaseClassType();
|
||||
PsiClass baseClass = baseClassType.resolve();
|
||||
if (baseClass == null || !baseClass.isInterface()) {
|
||||
return new PsiClassType[]{baseClassType};
|
||||
}
|
||||
else {
|
||||
PsiClassType objectType = PsiType.getJavaLangObject(getManager(), getResolveScope());
|
||||
return new PsiClassType[]{objectType, baseClassType};
|
||||
}
|
||||
return new PsiClassType[]{createTypeByName(GroovyCommonClassNames.GROOVY_OBJECT)};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-6
@@ -38,7 +38,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstantList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
import static com.intellij.psi.CommonClassNames.JAVA_LANG_ENUM;
|
||||
@@ -74,7 +73,7 @@ public class GrEnumTypeDefinitionImpl extends GrTypeDefinitionImpl implements Gr
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiClassType[] getExtendsListTypes(boolean includeSynthetic) {
|
||||
return new PsiClassType[]{createEnumType(), createGroovyObjectSupportType()};
|
||||
return new PsiClassType[]{createEnumType()};
|
||||
}
|
||||
|
||||
private PsiClassType createEnumType() {
|
||||
@@ -93,10 +92,6 @@ public class GrEnumTypeDefinitionImpl extends GrTypeDefinitionImpl implements Gr
|
||||
return TypesUtil.createTypeByFQClassName(JAVA_LANG_ENUM, this);
|
||||
}
|
||||
|
||||
private PsiClassType createGroovyObjectSupportType() {
|
||||
return TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public GrField[] getFields() {
|
||||
|
||||
+6
-9
@@ -98,12 +98,10 @@ public class GrTypeDefinitionMembersCache<T extends GrTypeDefinition> {
|
||||
if (includeSynthetic && TransformationUtilKt.isUnderTransformation(myDefinition)) includeSynthetic = false;
|
||||
return CachedValuesManager.getCachedValue(myDefinition, includeSynthetic ? () -> {
|
||||
PsiClassType[] extendsTypes = getTransformationResult().getExtendsTypes();
|
||||
PsiClassType[] result = GrClassImplUtil.getExtendsListTypes(myDefinition, extendsTypes);
|
||||
return CachedValueProvider.Result.create(result, myDependencies);
|
||||
return CachedValueProvider.Result.create(extendsTypes, myDependencies);
|
||||
} : () -> {
|
||||
PsiClassType[] extendsTypes = GrClassImplUtil.getReferenceListTypes(myDefinition.getExtendsClause());
|
||||
PsiClassType[] result = GrClassImplUtil.getExtendsListTypes(myDefinition, extendsTypes);
|
||||
return CachedValueProvider.Result.create(result, myDependencies);
|
||||
return CachedValueProvider.Result.create(extendsTypes, myDependencies);
|
||||
}).clone();
|
||||
}
|
||||
|
||||
@@ -112,18 +110,17 @@ public class GrTypeDefinitionMembersCache<T extends GrTypeDefinition> {
|
||||
if (includeSynthetic && TransformationUtilKt.isUnderTransformation(myDefinition)) includeSynthetic = false;
|
||||
return CachedValuesManager.getCachedValue(myDefinition, includeSynthetic ? () -> {
|
||||
PsiClassType[] implementsTypes = getTransformationResult().getImplementsTypes();
|
||||
PsiClassType[] result = GrClassImplUtil.getImplementsListTypes(myDefinition, implementsTypes);
|
||||
return CachedValueProvider.Result.create(result, myDependencies);
|
||||
return CachedValueProvider.Result.create(implementsTypes, myDependencies);
|
||||
} : () -> {
|
||||
PsiClassType[] implementsTypes = GrClassImplUtil.getReferenceListTypes(myDefinition.getImplementsClause());
|
||||
PsiClassType[] result = GrClassImplUtil.getImplementsListTypes(myDefinition, implementsTypes);
|
||||
return CachedValueProvider.Result.create(result, myDependencies);
|
||||
return CachedValueProvider.Result.create(implementsTypes, myDependencies);
|
||||
}).clone();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private TransformationResult getTransformationResult() {
|
||||
assert !TransformationUtilKt.isUnderTransformation(myDefinition);
|
||||
boolean underTransformation = TransformationUtilKt.isUnderTransformation(myDefinition);
|
||||
assert !underTransformation;
|
||||
return CachedValuesManager.getCachedValue(myDefinition, () -> CachedValueProvider.Result.create(
|
||||
TransformationUtilKt.transformDefinition(myDefinition), myDependencies
|
||||
));
|
||||
|
||||
+13
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.synthetic;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightTypeParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrPsiTypeStub;
|
||||
|
||||
@@ -33,6 +34,7 @@ public class GrMethodWrapper extends GrLightMethodBuilder implements PsiMirrorEl
|
||||
};
|
||||
|
||||
private final PsiMethod myWrappedMethod;
|
||||
private PsiElement myContext;
|
||||
private volatile boolean myNavigationElementInit;
|
||||
|
||||
protected GrMethodWrapper(PsiMethod method, PsiSubstitutor substitutor) {
|
||||
@@ -55,6 +57,16 @@ public class GrMethodWrapper extends GrLightMethodBuilder implements PsiMirrorEl
|
||||
setReturnType(TYPE_MARKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getContext() {
|
||||
if (myContext != null) return myContext;
|
||||
return super.getContext();
|
||||
}
|
||||
|
||||
public void setContext(@Nullable PsiElement context) {
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNavigationElement(@NotNull PsiElement navigationElement) {
|
||||
myNavigationElementInit = true;
|
||||
|
||||
-42
@@ -51,7 +51,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.GrTypeDefinitionImpl;
|
||||
@@ -67,9 +66,6 @@ import java.util.*;
|
||||
public class GrClassImplUtil {
|
||||
private static final Logger LOG = Logger.getInstance(GrClassImplUtil.class);
|
||||
|
||||
private static final Condition<PsiClassType> IS_GROOVY_OBJECT =
|
||||
psiClassType -> TypesUtil.isClassType(psiClassType, GroovyCommonClassNames.GROOVY_OBJECT);
|
||||
|
||||
private GrClassImplUtil() {
|
||||
}
|
||||
|
||||
@@ -126,44 +122,6 @@ public class GrClassImplUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClassType[] getExtendsListTypes(@NotNull GrTypeDefinition grType, @NotNull PsiClassType[] extendsTypes) {
|
||||
if (grType.isInterface()) {
|
||||
return extendsTypes;
|
||||
}
|
||||
|
||||
for (PsiClassType type : extendsTypes) {
|
||||
final PsiClass superClass = type.resolve();
|
||||
if (superClass instanceof GrTypeDefinition && !superClass.isInterface() ||
|
||||
superClass != null && GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(superClass.getQualifiedName())) {
|
||||
return extendsTypes;
|
||||
}
|
||||
}
|
||||
|
||||
PsiClass grObSupport = GroovyPsiManager.getInstance(grType.getProject())
|
||||
.findClassWithCache(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT, grType.getResolveScope());
|
||||
if (grObSupport != null) {
|
||||
final PsiClassType type = JavaPsiFacade.getInstance(grType.getProject()).getElementFactory().createType(grObSupport);
|
||||
return ArrayUtil.append(extendsTypes, type, PsiClassType.ARRAY_FACTORY);
|
||||
}
|
||||
return extendsTypes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClassType[] getImplementsListTypes(@NotNull GrTypeDefinition grType, @NotNull PsiClassType[] implementsTypes) {
|
||||
final Collection<PsiClassType> result = ContainerUtil.newLinkedHashSet();
|
||||
final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
|
||||
result.addAll(Arrays.asList(implementsTypes));
|
||||
if (!grType.isInterface() && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) && !ContainerUtil.or(extendsTypes, IS_GROOVY_OBJECT)) {
|
||||
result.add(getGroovyObjectType(grType));
|
||||
}
|
||||
return result.toArray(new PsiClassType[result.size()]);
|
||||
}
|
||||
|
||||
public static PsiClassType getGroovyObjectType(@NotNull PsiElement context) {
|
||||
return TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_OBJECT, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiClassType[] getSuperTypes(GrTypeDefinition grType, boolean includeSynthetic) {
|
||||
PsiClassType[] extendsList = grType.getExtendsListTypes(includeSynthetic);
|
||||
|
||||
+2
@@ -243,6 +243,8 @@ public class DelegateTransformationSupport implements AstTransformationSupport {
|
||||
);
|
||||
|
||||
private static boolean overridesObjectOrGroovyObject(PsiMethod method) {
|
||||
if (GroovyObjectTransformationSupport.isGroovyObjectSupportMethod(method)) return true;
|
||||
|
||||
final String name = method.getName();
|
||||
if (!OBJECT_METHODS.contains(name) && !GROOVY_OBJECT_METHODS.contains(name)) return false;
|
||||
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.transformations.impl
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.plugins.groovy.GroovyLanguage
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrMethodWrapper
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrTraitUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_OBJECT
|
||||
import org.jetbrains.plugins.groovy.transformations.AstTransformationSupport
|
||||
import org.jetbrains.plugins.groovy.transformations.TransformationContext
|
||||
|
||||
class GroovyObjectTransformationSupport : AstTransformationSupport {
|
||||
|
||||
companion object {
|
||||
private val ORIGIN_INFO = "via GroovyObject"
|
||||
private val KEY: Key<Boolean> = Key.create("groovy.object.method")
|
||||
|
||||
private fun TransformationContext.findClass(fqn: String) = psiFacade.findClass(fqn, resolveScope)
|
||||
@JvmStatic fun isGroovyObjectSupportMethod(method: PsiMethod) = method.getUserData(KEY) == true
|
||||
}
|
||||
|
||||
override fun applyTransformation(context: TransformationContext) {
|
||||
if (context.codeClass.isInterface) return
|
||||
if (context.superClass?.language == GroovyLanguage) return
|
||||
|
||||
val groovyObject = context.findClass(GROOVY_OBJECT)
|
||||
if (groovyObject == null || !GrTraitUtil.isInterface(groovyObject)) return
|
||||
|
||||
context.addInterface(TypesUtil.createType(groovyObject))
|
||||
|
||||
val implementedMethods = groovyObject.methods.map {
|
||||
GrMethodWrapper.wrap(it).apply {
|
||||
setContext(context.codeClass)
|
||||
modifierList.removeModifier(GrModifierFlags.ABSTRACT_MASK)
|
||||
originInfo = ORIGIN_INFO
|
||||
putUserData(KEY, true)
|
||||
}
|
||||
}
|
||||
context.addMethods(implementedMethods)
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,8 @@
|
||||
|
||||
<closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
|
||||
|
||||
<astTransformationSupport id="groovyObjectTransformation" order="first"
|
||||
implementation="org.jetbrains.plugins.groovy.transformations.impl.GroovyObjectTransformationSupport"/>
|
||||
<astTransformationSupport implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoExternalizeContributor"/>
|
||||
<astTransformationSupport implementation="org.jetbrains.plugins.groovy.transformations.impl.autoClone.AutoCloneTransformationSupport"/>
|
||||
<astTransformationSupport implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.ConstructorAnnotationsProcessor"/>
|
||||
@@ -343,6 +345,8 @@
|
||||
<renamePsiElementProcessor id="groovyLightElementRenamer"
|
||||
implementation="org.jetbrains.plugins.groovy.refactoring.rename.GrLightElementRenamer"
|
||||
order="first, after groovyPropertyRenameProcessor"/>
|
||||
<renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameGrReflectedMethodProcessor"
|
||||
order="first"/>
|
||||
<renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedClassProcessor"
|
||||
order="first"/>
|
||||
<renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.refactoring.rename.RenameAliasImportedMethodProcessor"
|
||||
@@ -351,6 +355,8 @@
|
||||
<renamePsiElementProcessor implementation="org.jetbrains.plugins.groovy.transformations.impl.synch.SynchronizedRenameFieldProcessor"
|
||||
order="first, before groovyFieldRenameProcessor"/>
|
||||
|
||||
<automaticRenamerFactory implementation="org.jetbrains.plugins.groovy.refactoring.rename.GroovyAutomaticOverloadsRenamerFactory"/>
|
||||
|
||||
<rename.inplace.resolveSnapshotProvider language="Groovy"
|
||||
implementationClass="org.jetbrains.plugins.groovy.refactoring.rename.inplace.GroovyResolveSnapshotProvider"/>
|
||||
|
||||
|
||||
+1
-3
@@ -94,9 +94,7 @@ class LogbackDelegateMemberContributor : NonCodeMembersContributor() {
|
||||
return true
|
||||
}
|
||||
val propertyName = method.name.removePrefix(prefix).decapitalize()
|
||||
if (name != null) assert(propertyName == name) {
|
||||
"$propertyName, $name"
|
||||
}
|
||||
if (name != null && name != propertyName) return true
|
||||
|
||||
val parameter = method.parameterList.parameters.singleOrNull() ?: return true
|
||||
val classType = wrapClassType(parameter.type, place) ?: return true
|
||||
|
||||
+2
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
@@ -117,7 +116,7 @@ public class AnonymousFromMapGenerator {
|
||||
final ExpressionContext extended = context.extend();
|
||||
extended.setInAnonymousContext(true);
|
||||
if (param == allParameters.length) {
|
||||
new CodeBlockGenerator(builder, extended).generateCodeBlock((GrCodeBlock)expression, false);
|
||||
new CodeBlockGenerator(builder, extended).generateCodeBlock(allParameters, closure, false);
|
||||
}
|
||||
else {
|
||||
builder.append("{\n");
|
||||
|
||||
+29
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -45,11 +45,15 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.transformations.impl.GroovyObjectTransformationSupport;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_OBJECT;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
@@ -146,7 +150,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
|
||||
GenerationUtil.writeThrowsList(builder, method.getThrowsList(), getMethodExceptions(method), classNameProvider);
|
||||
|
||||
if (!isAbstract) {
|
||||
/************* body **********/
|
||||
/* ************ body ********* */
|
||||
if (method instanceof GrMethod) {
|
||||
if (method instanceof GrReflectedMethod && ((GrReflectedMethod)method).getSkippedParameters().length > 0) {
|
||||
builder.append("{\n").append(generateDelegateCall((GrReflectedMethod)method)).append("\n}\n");
|
||||
@@ -184,7 +188,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
|
||||
for (GrParameter param : actualParams) {
|
||||
actual.add(param.getName());
|
||||
}
|
||||
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (method.isConstructor()) {
|
||||
builder.append("this");
|
||||
@@ -337,8 +341,10 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
|
||||
|
||||
@Override
|
||||
public Collection<PsiMethod> collectMethods(PsiClass typeDefinition) {
|
||||
List<PsiMethod> result = new ArrayList<>(Arrays.asList(typeDefinition.getMethods()));
|
||||
|
||||
List<PsiMethod> result = ContainerUtil.filter(
|
||||
typeDefinition.getMethods(),
|
||||
m -> !GroovyObjectTransformationSupport.isGroovyObjectSupportMethod(m)
|
||||
);
|
||||
if (typeDefinition instanceof GroovyScriptClass) {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.project);
|
||||
final String name = typeDefinition.getName();
|
||||
@@ -368,7 +374,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
|
||||
Map<PsiMethod, String> setters = context.getSetters();
|
||||
Set<Map.Entry<PsiMethod, String>> entries = setters.entrySet();
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
entries = ImmutableSortedSet.copyOf((o1, o2) -> o1.getValue().compareTo(o2.getValue()), entries);
|
||||
entries = ImmutableSortedSet.copyOf(Comparator.comparing(Map.Entry::getValue), entries);
|
||||
}
|
||||
for (Map.Entry<PsiMethod, String> entry : entries) {
|
||||
new SetterWriter(builder, psiClass, entry.getKey(), entry.getValue(), classNameProvider, context).write();
|
||||
@@ -404,29 +410,31 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
|
||||
}
|
||||
|
||||
private static boolean shouldSkipInImplements(PsiClass typeDefinition, PsiClassType implementsType) {
|
||||
return implementsType.equalsToText(GroovyCommonClassNames.GROOVY_OBJECT) &&
|
||||
typeDefinition instanceof GrTypeDefinition &&
|
||||
!typeDefinition.isInterface() &&
|
||||
!GenerationSettings.implementGroovyObjectAlways &&
|
||||
!isInList(implementsType, ((GrTypeDefinition)typeDefinition).getImplementsClause()) &&
|
||||
!containsMethodsOf((GrTypeDefinition)typeDefinition, GroovyCommonClassNames.GROOVY_OBJECT);
|
||||
return implementsType.equalsToText(GROOVY_OBJECT) &&
|
||||
typeDefinition instanceof GrTypeDefinition &&
|
||||
!typeDefinition.isInterface() &&
|
||||
!GenerationSettings.implementGroovyObjectAlways &&
|
||||
!isInList(implementsType, ((GrTypeDefinition)typeDefinition).getImplementsClause()) &&
|
||||
!containsMethodsOf((GrTypeDefinition)typeDefinition, GROOVY_OBJECT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExtendsList(StringBuilder text, PsiClass typeDefinition) {
|
||||
final PsiClassType[] extendsClassesTypes = typeDefinition.getExtendsListTypes();
|
||||
|
||||
PsiClassType type = null;
|
||||
if (extendsClassesTypes.length > 0) {
|
||||
PsiClassType type = extendsClassesTypes[0];
|
||||
|
||||
if (type.equalsToText(GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT) &&
|
||||
typeDefinition instanceof GrTypeDefinition &&
|
||||
!GenerationSettings.implementGroovyObjectAlways &&
|
||||
!isInList(type, ((GrTypeDefinition)typeDefinition).getExtendsClause()) &&
|
||||
!containsMethodsOf((GrTypeDefinition)typeDefinition, GroovyCommonClassNames.GROOVY_OBJECT)) {
|
||||
return;
|
||||
type = extendsClassesTypes[0];
|
||||
}
|
||||
else {
|
||||
if (typeDefinition instanceof GrTypeDefinition) {
|
||||
if (GenerationSettings.implementGroovyObjectAlways || containsMethodsOf((GrTypeDefinition)typeDefinition, GROOVY_OBJECT)) {
|
||||
type = TypesUtil.createType(GROOVY_OBJECT_SUPPORT, typeDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
text.append("extends ");
|
||||
TypeWriter.writeType(text, type, typeDefinition, classNameProvider);
|
||||
text.append(' ');
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -94,7 +94,7 @@ public class ClosureGenerator {
|
||||
boolean shouldInsertReturnNull = !(returnType instanceof PsiPrimitiveType) &&
|
||||
MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.shouldNotReturnValue);
|
||||
|
||||
new CodeBlockGenerator(builder, context.extend(), myExitPoints).generateCodeBlock(block, shouldInsertReturnNull);
|
||||
new CodeBlockGenerator(builder, context.extend(), myExitPoints).generateCodeBlock(parameters, block, shouldInsertReturnNull);
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
|
||||
+13
-14
@@ -55,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.transformations.impl.GroovyObjectTransformationSupport;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
@@ -101,7 +102,10 @@ public class CodeBlockGenerator extends Generator {
|
||||
boolean shouldInsertReturnNull;
|
||||
myExitPoints.clear();
|
||||
PsiType returnType = context.typeProvider.getReturnType(method);
|
||||
if (!method.isConstructor() && !PsiType.VOID.equals(returnType)) {
|
||||
if (GroovyObjectTransformationSupport.isGroovyObjectSupportMethod(method)) {
|
||||
shouldInsertReturnNull = !(returnType instanceof PsiPrimitiveType);
|
||||
}
|
||||
else if (!method.isConstructor() && !PsiType.VOID.equals(returnType)) {
|
||||
myExitPoints.addAll(ControlFlowUtils.collectReturns(block));
|
||||
shouldInsertReturnNull = block != null &&
|
||||
!(returnType instanceof PsiPrimitiveType) &&
|
||||
@@ -112,9 +116,7 @@ public class CodeBlockGenerator extends Generator {
|
||||
shouldInsertReturnNull = false;
|
||||
}
|
||||
|
||||
if (block != null) {
|
||||
generateCodeBlock(block, shouldInsertReturnNull);
|
||||
}
|
||||
generateCodeBlock(method.getParameters(), block, shouldInsertReturnNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,22 +126,19 @@ public class CodeBlockGenerator extends Generator {
|
||||
|
||||
@Override
|
||||
public void visitOpenBlock(@NotNull GrOpenBlock block) {
|
||||
generateCodeBlock(block, false);
|
||||
}
|
||||
|
||||
public void generateCodeBlock(GrCodeBlock block, boolean shouldInsertReturnNull) {
|
||||
builder.append("{");
|
||||
GrParameter[] parameters;
|
||||
if (block.getParent() instanceof GrMethod) {
|
||||
GrMethod method = (GrMethod)block.getParent();
|
||||
parameters = method.getParameters();
|
||||
}
|
||||
else if (block instanceof GrClosableBlock) {
|
||||
parameters = ((GrClosableBlock)block).getAllParameters();
|
||||
}
|
||||
else {
|
||||
parameters = GrParameter.EMPTY_ARRAY;
|
||||
}
|
||||
generateCodeBlock(parameters, block, false);
|
||||
}
|
||||
|
||||
public void generateCodeBlock(@NotNull GrParameter[] parameters, @Nullable GrCodeBlock block, boolean shouldInsertReturnNull) {
|
||||
builder.append("{");
|
||||
|
||||
for (GrParameter parameter : parameters) {
|
||||
if (context.analyzedVars.toWrap(parameter)) {
|
||||
@@ -154,9 +153,9 @@ public class CodeBlockGenerator extends Generator {
|
||||
builder.append("}\n");
|
||||
}
|
||||
|
||||
public void visitStatementOwner(GrStatementOwner owner, boolean shouldInsertReturnNull) {
|
||||
public void visitStatementOwner(@Nullable GrStatementOwner owner, boolean shouldInsertReturnNull) {
|
||||
boolean hasLineFeed = false;
|
||||
for (PsiElement e = owner.getFirstChild(); e != null; e = e.getNextSibling()) {
|
||||
for (PsiElement e = owner == null ? null : owner.getFirstChild(); e != null; e = e.getNextSibling()) {
|
||||
if (e instanceof GrStatement) {
|
||||
((GrStatement)e).accept(this);
|
||||
hasLineFeed = false;
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.jetbrains.plugins.groovy.refactoring.rename
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.refactoring.rename.naming.AutomaticOverloadsRenamer
|
||||
import com.intellij.refactoring.rename.naming.AutomaticOverloadsRenamerFactory
|
||||
import com.intellij.refactoring.rename.naming.AutomaticRenamer
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod
|
||||
|
||||
class GroovyAutomaticOverloadsRenamerFactory : AutomaticOverloadsRenamerFactory() {
|
||||
|
||||
override fun isApplicable(element: PsiElement): Boolean {
|
||||
if (element !is GrMethod || element.isConstructor) return false
|
||||
val containingClass = element.containingClass ?: return false
|
||||
val allSameNameMethods = containingClass.findMethodsByName(element.name, false)
|
||||
return allSameNameMethods.filter {
|
||||
it !is GrReflectedMethod || it.baseMethod !== element
|
||||
}.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun createRenamer(element: PsiElement?, newName: String?, usages: MutableCollection<UsageInfo>?): AutomaticRenamer {
|
||||
return object : AutomaticOverloadsRenamer(element as GrMethod, newName) {
|
||||
override fun getOverloads(method: PsiMethod): Array<out PsiMethod> {
|
||||
val containingClass = method.containingClass ?: return PsiMethod.EMPTY_ARRAY
|
||||
val allSameNameMethods = containingClass.findMethodsByName(method.name, false)
|
||||
return allSameNameMethods.mapNotNullTo(mutableSetOf()) {
|
||||
if (it !is GrReflectedMethod) {
|
||||
it
|
||||
}
|
||||
else {
|
||||
val baseMethod = it.baseMethod
|
||||
if (baseMethod !== method) baseMethod else null
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.jetbrains.plugins.groovy.refactoring.rename
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
|
||||
class RenameGrReflectedMethodProcessor : RenameAliasImportedMethodProcessor() {
|
||||
|
||||
override fun canProcessElement(element: PsiElement): Boolean {
|
||||
return element is GrMethod && element.reflectedMethods.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun isInplaceRenameSupported() = false
|
||||
}
|
||||
+1
-1
@@ -172,6 +172,7 @@ overridden
|
||||
thisProp
|
||||
fromSuper
|
||||
fromSuper2
|
||||
metaClass
|
||||
metaPropertyValues
|
||||
properties
|
||||
superProp
|
||||
@@ -181,7 +182,6 @@ getProperty
|
||||
hashCode
|
||||
identity
|
||||
invokeMethod
|
||||
metaClass
|
||||
notify
|
||||
notifyAll
|
||||
setProperty
|
||||
|
||||
@@ -179,4 +179,25 @@ appender('FOO_<caret>APP', ConsoleAppender)
|
||||
assert targetElement.target instanceof AppenderTarget
|
||||
}
|
||||
}
|
||||
|
||||
void 'test no error when class with same name exists'() {
|
||||
fixture.with {
|
||||
addClass '''\
|
||||
package pckg1;
|
||||
public class SomeClass {}
|
||||
'''
|
||||
addClass '''
|
||||
package pckg2;
|
||||
public class SomeConfigurableClass {
|
||||
public void setSomeClass(pckg1.SomeClass someClass) {}
|
||||
}'''
|
||||
configureByText 'logback.groovy', '''\
|
||||
appender('foo', pckg2.SomeConfigurableClass) {
|
||||
someClass = SomeClass.<caret>
|
||||
}
|
||||
'''
|
||||
enableInspections GrUnresolvedAccessInspection
|
||||
completeBasic()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1605,15 +1605,15 @@ A.foo = 3 //no error
|
||||
|
||||
void testSOEIfExtendsItself() {
|
||||
testHighlighting('''\
|
||||
<error descr="Cyclic inheritance involving 'A'"><error descr="Method 'invokeMethod' is not implemented">class A extends A</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'A'">class A extends A</error> {
|
||||
def foo
|
||||
}
|
||||
|
||||
<error descr="Cyclic inheritance involving 'B'"><error descr="Method 'invokeMethod' is not implemented">class B extends C</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'B'">class B extends C</error> {
|
||||
def foo
|
||||
}
|
||||
|
||||
<error descr="Cyclic inheritance involving 'C'"><error descr="Method 'invokeMethod' is not implemented">class C extends B</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'C'">class C extends B</error> {
|
||||
}
|
||||
''')
|
||||
}
|
||||
|
||||
+4
-1
@@ -61,7 +61,10 @@ new Roo<Double>() {}
|
||||
def inheritors = DirectClassInheritorsSearch.search(iface).findAll()
|
||||
assert inheritors.size() == 4
|
||||
inheritors.each {
|
||||
def type = (it as GrTypeDefinition).getImplementsListTypes(false).first()
|
||||
def type = (it as GrTypeDefinition).getSuperTypes(false).find {
|
||||
it.resolve() == iface
|
||||
}
|
||||
assert type != null
|
||||
def resolveResult = type.resolveGenerics()
|
||||
assert resolveResult.element == iface
|
||||
assert resolveResult.substitutor.substitute(iface.typeParameters.first())
|
||||
|
||||
+4
-4
@@ -47,7 +47,7 @@ class GroovyResolveCacheTest extends LightGroovyTestCase {
|
||||
def clazz = file.typeDefinitions.first()
|
||||
|
||||
assert counter == 0
|
||||
assert clazz.methods.size() == 1
|
||||
assert clazz.methods.size() == 6
|
||||
assert counter == 1
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(project) {
|
||||
@@ -55,7 +55,7 @@ class GroovyResolveCacheTest extends LightGroovyTestCase {
|
||||
}
|
||||
|
||||
assert counter == 1
|
||||
assert clazz.methods.size() == 0
|
||||
assert clazz.methods.size() == 5
|
||||
assert counter == 2
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class GroovyResolveCacheTest extends LightGroovyTestCase {
|
||||
def clazz = file.typeDefinitions.first()
|
||||
|
||||
assert counter == 0
|
||||
assert clazz.methods.size() == 1
|
||||
assert clazz.methods.size() == 6
|
||||
assert (clazz.methods.first() as GrMethod).block.statements.size() == 1
|
||||
assert counter == 1
|
||||
|
||||
@@ -79,7 +79,7 @@ class GroovyResolveCacheTest extends LightGroovyTestCase {
|
||||
}
|
||||
|
||||
assert counter == 1
|
||||
assert clazz.methods.size() == 1
|
||||
assert clazz.methods.size() == 6
|
||||
assert (clazz.methods.first() as GrMethod).block.statements.size() == 0
|
||||
assert counter == 1
|
||||
}
|
||||
|
||||
@@ -759,4 +759,22 @@ trait T2 extends T {
|
||||
''')
|
||||
}
|
||||
}
|
||||
|
||||
void 'test rename reflected method with overloads'() {
|
||||
fixture.with {
|
||||
configureByText '_.groovy', '''\
|
||||
class A {
|
||||
def fo<caret>o(a, b, c = 1) {}
|
||||
def foo(d = 2) {}
|
||||
}
|
||||
'''
|
||||
renameElementAtCaretUsingHandler 'foo1'
|
||||
checkResult '''\
|
||||
class A {
|
||||
def foo1(a, b, c = 1) {}
|
||||
def foo1(d = 2) {}
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<error descr="Cyclic inheritance involving 'Foo'"><error descr="Method 'invokeMethod' is not implemented">class Foo extends Bar</error></error> {}
|
||||
<error descr="Cyclic inheritance involving 'Bar'"><error descr="Method 'invokeMethod' is not implemented">class Bar extends Foo</error></error> {}
|
||||
<error descr="Cyclic inheritance involving 'Foo'">class Foo extends Bar</error> {}
|
||||
<error descr="Cyclic inheritance involving 'Bar'">class Bar extends Foo</error> {}
|
||||
|
||||
println(new Foo())
|
||||
@@ -1,15 +1,15 @@
|
||||
<error descr="Cyclic inheritance involving 'A'"><error descr="Method 'invokeMethod' is not implemented">class A extends C</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'A'">class A extends C</error> {
|
||||
|
||||
}
|
||||
|
||||
<error descr="Cyclic inheritance involving 'B'"><error descr="Method 'invokeMethod' is not implemented">class B extends A</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'B'">class B extends A</error> {
|
||||
|
||||
}
|
||||
|
||||
<error descr="Cyclic inheritance involving 'C'"><error descr="Method 'invokeMethod' is not implemented">class C extends B</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'C'">class C extends B</error> {
|
||||
|
||||
}
|
||||
|
||||
<error descr="Cyclic inheritance involving 'B'"><error descr="Method 'invokeMethod' is not implemented">class D extends B</error></error> {
|
||||
<error descr="Cyclic inheritance involving 'B'">class D extends B</error> {
|
||||
|
||||
}
|
||||
+3
-3
@@ -10,8 +10,8 @@ org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, getProperty("bar"))
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar);
|
||||
}
|
||||
|
||||
private static <Value>Value setProperty0(groovy.lang.GroovyObjectSupport propOwner, java.lang.String property, Value newValue) {
|
||||
propOwner.setProperty(property, newValue);
|
||||
return newValue;
|
||||
private static <Value>Value setProperty0(A propOwner, java.lang.String s, Value o) {
|
||||
propOwner.setProperty(s, o);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ internal const val PLUGIN_NAME = "Settings Repository"
|
||||
|
||||
internal val LOG = logger<IcsManager>()
|
||||
|
||||
val icsManager by lazy(LazyThreadSafetyMode.NONE) {
|
||||
internal val icsManager by lazy(LazyThreadSafetyMode.NONE) {
|
||||
ApplicationLoadListener.EP_NAME.findExtension(IcsApplicationLoadListener::class.java).icsManager
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
|
||||
val settings: IcsSettings
|
||||
val repositoryManager: RepositoryManager = GitRepositoryManager(credentialsStore, dir.resolve("repository"))
|
||||
val readOnlySourcesManager = ReadOnlySourceManager(this, dir)
|
||||
|
||||
init {
|
||||
settings = try {
|
||||
@@ -69,8 +70,6 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
}
|
||||
}
|
||||
|
||||
val readOnlySourcesManager = ReadOnlySourceManager(settings, dir)
|
||||
|
||||
val repositoryService: RepositoryService = GitRepositoryService()
|
||||
|
||||
private val commitAlarm = SingleAlarm(Runnable {
|
||||
@@ -98,7 +97,11 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
}
|
||||
|
||||
inner class ApplicationLevelProvider : IcsStreamProvider(null) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (syncManager.writeAndDeleteProhibited) {
|
||||
throw IllegalStateException("Delete is prohibited now")
|
||||
}
|
||||
@@ -106,6 +109,8 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
if (repositoryManager.delete(toRepositoryPath(fileSpec, roamingType))) {
|
||||
scheduleCommit()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +184,9 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
override val enabled: Boolean
|
||||
get() = this@IcsManager.active
|
||||
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = enabled
|
||||
override fun isApplicable(fileSpec: String, roamingType: RoamingType): Boolean = repositoryActive
|
||||
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean) {
|
||||
override fun processChildren(path: String, roamingType: RoamingType, filter: (name: String) -> Boolean, processor: (name: String, input: InputStream, readOnly: Boolean) -> Boolean): Boolean {
|
||||
val fullPath = toRepositoryPath(path, roamingType, null)
|
||||
|
||||
// first of all we must load read-only schemes - scheme could be overridden if bundled or read-only, so, such schemes must be loaded first
|
||||
@@ -189,7 +194,12 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
repository.processChildren(fullPath, filter) { name, input -> processor(name, input, true) }
|
||||
}
|
||||
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
repositoryManager.processChildren(fullPath, filter) { name, input -> processor(name, input, false) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun write(fileSpec: String, content: ByteArray, size: Int, roamingType: RoamingType) {
|
||||
@@ -206,9 +216,17 @@ class IcsManager @JvmOverloads constructor(dir: Path, val schemeManagerFactory:
|
||||
|
||||
protected open fun isAutoCommit(fileSpec: String, roamingType: RoamingType) = true
|
||||
|
||||
override fun <R> read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> R): R = repositoryManager.read(toRepositoryPath(fileSpec, roamingType, projectId), consumer)
|
||||
override fun read(fileSpec: String, roamingType: RoamingType, consumer: (InputStream?) -> Unit): Boolean {
|
||||
if (!repositoryActive) {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType) {
|
||||
repositoryManager.read(toRepositoryPath(fileSpec, roamingType, projectId), consumer)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun delete(fileSpec: String, roamingType: RoamingType): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,6 +236,10 @@ class IcsApplicationLoadListener : ApplicationLoadListener {
|
||||
private set
|
||||
|
||||
override fun beforeApplicationLoaded(application: Application, configPath: String) {
|
||||
if (application.isUnitTestMode) {
|
||||
return
|
||||
}
|
||||
|
||||
val customPath = System.getProperty("ics.settingsRepository")
|
||||
val pluginSystemDir = if (customPath == null) Paths.get(configPath, "settingsRepository") else Paths.get(FileUtil.expandUserHome(customPath))
|
||||
icsManager = IcsManager(pluginSystemDir)
|
||||
|
||||
@@ -33,14 +33,14 @@ import org.jetbrains.settingsRepository.git.upstream
|
||||
import org.jetbrains.settingsRepository.git.use
|
||||
import java.nio.file.Path
|
||||
|
||||
class ReadOnlySourceManager(private val settings: IcsSettings, val rootDir: Path) {
|
||||
class ReadOnlySourceManager(private val icsManager: IcsManager, val rootDir: Path) {
|
||||
private val repositoryList = object : AtomicClearableLazyValue<List<Repository>>() {
|
||||
override fun compute(): List<Repository> {
|
||||
if (settings.readOnlySources.isEmpty()) {
|
||||
if (icsManager.settings.readOnlySources.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return settings.readOnlySources.mapSmartNotNull { source ->
|
||||
return icsManager.settings.readOnlySources.mapSmartNotNull { source ->
|
||||
LOG.catchAndLog {
|
||||
if (!source.active) {
|
||||
return@mapSmartNotNull null
|
||||
@@ -64,7 +64,7 @@ class ReadOnlySourceManager(private val settings: IcsSettings, val rootDir: Path
|
||||
get() = repositoryList.value
|
||||
|
||||
fun setSources(sources: List<ReadonlySource>) {
|
||||
settings.readOnlySources = sources
|
||||
icsManager.settings.readOnlySources = sources
|
||||
repositoryList.drop()
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ internal class AutoSyncManager(private val icsManager: IcsManager) {
|
||||
if (!onAppExit &&
|
||||
!app.isDisposeInProgress &&
|
||||
updateResult != null &&
|
||||
updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) {
|
||||
updateStoragesFromStreamProvider(icsManager, app.stateStore as ComponentStoreImpl, updateResult, app.messageBus)) {
|
||||
// force to avoid saveAll & confirmation
|
||||
app.exit(true, true, true)
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ open internal class Pull(val manager: GitRepositoryClient, val indicator: Progre
|
||||
if (headId == null) {
|
||||
revWalk.parseHeaders(srcCommit)
|
||||
dirCacheCheckout = DirCacheCheckout(repository, repository.lockDirCache(), srcCommit.tree)
|
||||
dirCacheCheckout.setFailOnConflict(true)
|
||||
dirCacheCheckout.setFailOnConflict(false)
|
||||
dirCacheCheckout.checkout()
|
||||
val refUpdate = repository.updateRef(head.target.name)
|
||||
refUpdate.setNewObjectId(objectId)
|
||||
@@ -187,7 +187,7 @@ open internal class Pull(val manager: GitRepositoryClient, val indicator: Progre
|
||||
// FAST_FORWARD detected: skip doing a real merge but only update HEAD
|
||||
refLogMessage.append(": ").append(MergeStatus.FAST_FORWARD)
|
||||
dirCacheCheckout = DirCacheCheckout(repository, headCommit.tree, repository.lockDirCache(), srcCommit.tree)
|
||||
dirCacheCheckout.setFailOnConflict(true)
|
||||
dirCacheCheckout.setFailOnConflict(false)
|
||||
dirCacheCheckout.checkout()
|
||||
val mergeStatus: MergeStatus
|
||||
if (squash) {
|
||||
@@ -241,7 +241,7 @@ open internal class Pull(val manager: GitRepositoryClient, val indicator: Progre
|
||||
// ResolveMerger does checkout
|
||||
if (merger !is ResolveMerger) {
|
||||
dirCacheCheckout = DirCacheCheckout(repository, headCommit.tree, repository.lockDirCache(), merger.resultTreeId)
|
||||
dirCacheCheckout.setFailOnConflict(true)
|
||||
dirCacheCheckout.setFailOnConflict(false)
|
||||
dirCacheCheckout.checkout()
|
||||
result = ImmutableUpdateResult(dirCacheCheckout.updated.keys, dirCacheCheckout.removed)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.settingsRepository.git
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import org.eclipse.jgit.api.MergeResult
|
||||
import org.eclipse.jgit.lib.RepositoryState
|
||||
import org.eclipse.jgit.merge.MergeStrategy
|
||||
import org.jetbrains.settingsRepository.LOG
|
||||
import org.jetbrains.settingsRepository.MutableUpdateResult
|
||||
@@ -67,6 +68,10 @@ internal class Reset(manager: GitRepositoryManager, indicator: ProgressIndicator
|
||||
return result
|
||||
}
|
||||
|
||||
if (repository.repositoryState == RepositoryState.MERGING) {
|
||||
repository.resetHard()
|
||||
}
|
||||
|
||||
val secondMergeResult = merge(latestUpstreamCommit, mergeStrategy, true, forceMerge = true, commitMessage = commitMessage)
|
||||
if (!secondMergeResult.status.isSuccessful) {
|
||||
throw IllegalStateException(secondMergeResult.toString())
|
||||
|
||||
@@ -15,19 +15,20 @@
|
||||
*/
|
||||
package org.jetbrains.settingsRepository
|
||||
|
||||
import com.intellij.openapi.diagnostic.catchAndLog
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.options.ConfigurableUi
|
||||
import com.intellij.openapi.progress.runModalTask
|
||||
import com.intellij.openapi.ui.DialogBuilder
|
||||
import com.intellij.openapi.ui.TextBrowseFolderListener
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.ui.DocumentAdapter
|
||||
import com.intellij.util.Function
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.intellij.util.io.delete
|
||||
import com.intellij.util.io.exists
|
||||
import com.intellij.util.text.nullize
|
||||
import com.intellij.util.text.trimMiddle
|
||||
import com.intellij.util.ui.FormBuilder
|
||||
import com.intellij.util.ui.table.TableModelEditor
|
||||
import gnu.trove.THashSet
|
||||
@@ -117,34 +118,33 @@ internal fun createReadOnlySourcesEditor(): ConfigurableUi<IcsSettings> {
|
||||
indicator.text = "Deleting old repositories"
|
||||
for (path in toDelete) {
|
||||
indicator.checkCanceled()
|
||||
try {
|
||||
LOG.catchAndLog {
|
||||
indicator.text2 = path
|
||||
root.resolve(path).delete()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toCheckout.isNotEmpty()) {
|
||||
for (source in toCheckout) {
|
||||
indicator.checkCanceled()
|
||||
try {
|
||||
indicator.text = "Cloning ${StringUtil.trimMiddle(source.url!!, 255)}"
|
||||
LOG.catchAndLog {
|
||||
indicator.text = "Cloning ${source.url!!.trimMiddle(255)}"
|
||||
val dir = root.resolve(source.path!!)
|
||||
if (dir.exists()) {
|
||||
dir.delete()
|
||||
}
|
||||
cloneBare(source.url!!, dir, icsManager.credentialsStore, indicator.asProgressMonitor()).close()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
icsManager.readOnlySourcesManager.setSources(newList)
|
||||
|
||||
// blindly reload all
|
||||
icsManager.schemeManagerFactory.value.process {
|
||||
it.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,17 +50,18 @@ internal fun createRepositoryListEditor(): ConfigurableUi<IcsSettings> {
|
||||
}
|
||||
|
||||
return object: ConfigurableUi<IcsSettings> {
|
||||
private var noRepositoryRow: Row? = null
|
||||
private var repositoryRow: Row? = null
|
||||
|
||||
override fun isModified(settings: IcsSettings) = editor.isModified
|
||||
|
||||
override fun getComponent() = panel {
|
||||
row("Repository:") {
|
||||
if (editor.model.isEmpty) {
|
||||
hint("Use File -> Settings Repository... to configure")
|
||||
}
|
||||
else {
|
||||
editor.comboBox()
|
||||
deleteButton()
|
||||
}
|
||||
noRepositoryRow = row("Repository:") {
|
||||
hint("Use File -> Settings Repository... to configure")
|
||||
}
|
||||
repositoryRow = row("Repository:") {
|
||||
editor.comboBox()
|
||||
deleteButton()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +83,9 @@ internal fun createRepositoryListEditor(): ConfigurableUi<IcsSettings> {
|
||||
editor.reset(list)
|
||||
editor.model.selectedItem = upstream
|
||||
|
||||
noRepositoryRow!!.visible = list.isEmpty()
|
||||
repositoryRow!!.visible = list.isNotEmpty()
|
||||
|
||||
deleteButton.isEnabled = editor.model.selectedItem != null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ internal class SyncManager(private val icsManager: IcsManager, private val autoS
|
||||
|
||||
if (updateResult != null) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
restartApplication = updateStoragesFromStreamProvider(app.stateStore as ComponentStoreImpl, updateResult!!, app.messageBus,
|
||||
restartApplication = updateStoragesFromStreamProvider(icsManager, app.stateStore as ComponentStoreImpl, updateResult!!, app.messageBus,
|
||||
reloadAllSchemes = syncType == SyncType.OVERWRITE_LOCAL)
|
||||
}
|
||||
}
|
||||
@@ -158,30 +158,28 @@ internal class SyncManager(private val icsManager: IcsManager, private val autoS
|
||||
}
|
||||
return updateResult != null || isReadOnlySourcesChanged
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCloudSchemes(indicator: ProgressIndicator): Boolean {
|
||||
val changedRootDirs = icsManager.readOnlySourcesManager.update(indicator) ?: return false
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
icsManager.schemeManagerFactory.value.process {
|
||||
val fileSpec = toRepositoryPath(it.fileSpec, it.roamingType)
|
||||
if (changedRootDirs.contains(fileSpec)) {
|
||||
schemeManagersToReload.add(it)
|
||||
private fun updateCloudSchemes(indicator: ProgressIndicator): Boolean {
|
||||
val changedRootDirs = icsManager.readOnlySourcesManager.update(indicator) ?: return false
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
icsManager.schemeManagerFactory.value.process {
|
||||
val fileSpec = toRepositoryPath(it.fileSpec, it.roamingType)
|
||||
if (changedRootDirs.contains(fileSpec)) {
|
||||
schemeManagersToReload.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (schemeManagersToReload.isNotEmpty()) {
|
||||
invokeAndWaitIfNeed {
|
||||
if (schemeManagersToReload.isNotEmpty()) {
|
||||
for (schemeManager in schemeManagersToReload) {
|
||||
schemeManager.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schemeManagersToReload.isNotEmpty()
|
||||
return schemeManagersToReload.isNotEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun updateStoragesFromStreamProvider(store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus, reloadAllSchemes: Boolean = false): Boolean {
|
||||
internal fun updateStoragesFromStreamProvider(icsManager: IcsManager, store: ComponentStoreImpl, updateResult: UpdateResult, messageBus: MessageBus, reloadAllSchemes: Boolean = false): Boolean {
|
||||
val (changed, deleted) = (store.storageManager as StateStorageManagerImpl).getCachedFileStorages(updateResult.changed, updateResult.deleted, ::toIdeaPath)
|
||||
|
||||
val schemeManagersToReload = SmartList<SchemeManagerImpl<*, *>>()
|
||||
|
||||
Reference in New Issue
Block a user