Merge remote-tracking branch 'origin/master'
@@ -70,8 +70,7 @@ import org.jetbrains.jps.client.CompileServerClient;
|
||||
import org.jetbrains.jps.server.ClasspathBootstrap;
|
||||
import org.jetbrains.jps.server.Server;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.ToolProvider;
|
||||
import javax.tools.*;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -586,6 +585,10 @@ public class CompileServerManager implements ApplicationComponent{
|
||||
cmdLine.addParameter("-XX:ReservedCodeCacheSize=64m");
|
||||
cmdLine.addParameter("-Xmx" + Registry.intValue("compiler.server.heap.size") + "m");
|
||||
cmdLine.addParameter("-Djava.awt.headless=true");
|
||||
final String shouldGenerateIndex = System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION);
|
||||
if (shouldGenerateIndex != null) {
|
||||
cmdLine.addParameter("-D"+ GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION +"=" + shouldGenerateIndex);
|
||||
}
|
||||
//noinspection ConstantConditions
|
||||
if (pingInterval > 0L) {
|
||||
cmdLine.addParameter("-D" + GlobalOptions.PING_INTERVAL_MS_OPTION + "=" + pingInterval);
|
||||
|
||||
@@ -32,20 +32,13 @@ import com.sun.jdi.ReferenceType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author lex
|
||||
*/
|
||||
class ReloadClassesWorker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.ReloadClassesWorker");
|
||||
/**
|
||||
* number of clasess that will be reloaded in one go.
|
||||
* Such restriction is needed to deal with big number of classes being reloaded
|
||||
*/
|
||||
private static final int CLASSES_CHUNK_SIZE = 100;
|
||||
private final DebuggerSession myDebuggerSession;
|
||||
private final HotSwapProgress myProgress;
|
||||
|
||||
@@ -111,11 +104,12 @@ class ReloadClassesWorker {
|
||||
final Project project = debugProcess.getProject();
|
||||
final BreakpointManager breakpointManager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager();
|
||||
breakpointManager.disableBreakpoints(debugProcess);
|
||||
|
||||
|
||||
//virtualMachineProxy.suspend();
|
||||
|
||||
|
||||
try {
|
||||
final Map<ReferenceType, byte[]> redefineMap = new HashMap<ReferenceType,byte[]>();
|
||||
RedefineProcessor redefineProcessor = new RedefineProcessor(virtualMachineProxy);
|
||||
|
||||
int processedClassesCount = 0;
|
||||
for (final String qualifiedName : modifiedClasses.keySet()) {
|
||||
processedClassesCount++;
|
||||
@@ -124,32 +118,30 @@ class ReloadClassesWorker {
|
||||
myProgress.setFraction(processedClassesCount / (double)modifiedClasses.size());
|
||||
}
|
||||
final HotSwapFile fileDescr = modifiedClasses.get(qualifiedName);
|
||||
final byte[] content;
|
||||
try {
|
||||
final byte[] buffer = FileUtil.loadFileBytes(fileDescr.file);
|
||||
final List<ReferenceType> classes = virtualMachineProxy.classesByName(qualifiedName);
|
||||
for (final ReferenceType reference : classes) {
|
||||
redefineMap.put(reference, buffer);
|
||||
}
|
||||
content = FileUtil.loadFileBytes(fileDescr.file);
|
||||
}
|
||||
catch (IOException e) {
|
||||
reportProblem(qualifiedName, e);
|
||||
continue;
|
||||
}
|
||||
if (redefineMap.size() >= CLASSES_CHUNK_SIZE) {
|
||||
// reload this portion of clasess and clear the map to free memory
|
||||
try {
|
||||
virtualMachineProxy.redefineClasses(redefineMap);
|
||||
}
|
||||
finally {
|
||||
redefineMap.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (redefineMap.size() > 0) {
|
||||
virtualMachineProxy.redefineClasses(redefineMap);
|
||||
redefineProcessor.processClass(qualifiedName, content);
|
||||
}
|
||||
redefineProcessor.processPending();
|
||||
myProgress.setFraction(1);
|
||||
|
||||
myProgress.addMessage(myDebuggerSession, MessageCategory.INFORMATION, DebuggerBundle.message("status.classes.reloaded", modifiedClasses.size()));
|
||||
|
||||
final int partiallyRedefinedClassesCount = redefineProcessor.getPartiallyRedefinedClassesCount();
|
||||
if (partiallyRedefinedClassesCount == 0) {
|
||||
myProgress.addMessage(myDebuggerSession, MessageCategory.INFORMATION,
|
||||
DebuggerBundle.message("status.classes.reloaded", redefineProcessor.getProcessedClassesCount()));
|
||||
}
|
||||
else {
|
||||
final String message = DebuggerBundle.message("status.classes.not.all.versions.reloaded", partiallyRedefinedClassesCount,
|
||||
redefineProcessor.getProcessedClassesCount());
|
||||
myProgress.addMessage(myDebuggerSession, MessageCategory.WARNING, message);
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("classes reloaded");
|
||||
}
|
||||
@@ -203,11 +195,10 @@ class ReloadClassesWorker {
|
||||
catch (Exception e) {
|
||||
processException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void reportProblem(final String qualifiedName, @Nullable Exception ex) {
|
||||
String reason = null;
|
||||
String reason = null;
|
||||
if (ex != null) {
|
||||
reason = ex.getLocalizedMessage();
|
||||
}
|
||||
@@ -223,4 +214,78 @@ class ReloadClassesWorker {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RedefineProcessor {
|
||||
/**
|
||||
* number of classes that will be reloaded in one go.
|
||||
* Such restriction is needed to deal with big number of classes being reloaded
|
||||
*/
|
||||
private static final int CLASSES_CHUNK_SIZE = 100;
|
||||
private final VirtualMachineProxyImpl myVirtualMachineProxy;
|
||||
private final Map<ReferenceType, byte[]> myRedefineMap = new HashMap<ReferenceType, byte[]>();
|
||||
private int myProcessedClassesCount;
|
||||
private int myPartiallyRedefinedClassesCount;
|
||||
|
||||
public RedefineProcessor(VirtualMachineProxyImpl virtualMachineProxy) {
|
||||
myVirtualMachineProxy = virtualMachineProxy;
|
||||
}
|
||||
|
||||
public void processClass(String qualifiedName, byte[] content) throws Throwable {
|
||||
final List<ReferenceType> vmClasses = myVirtualMachineProxy.classesByName(qualifiedName);
|
||||
if (vmClasses.isEmpty()) return;
|
||||
|
||||
if (vmClasses.size() == 1) {
|
||||
myRedefineMap.put(vmClasses.get(0), content);
|
||||
if (myRedefineMap.size() >= CLASSES_CHUNK_SIZE) {
|
||||
processChunk();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int redefinedVersionsCount = 0;
|
||||
Throwable error = null;
|
||||
for (ReferenceType vmClass : vmClasses) {
|
||||
try {
|
||||
myVirtualMachineProxy.redefineClasses(Collections.singletonMap(vmClass, content));
|
||||
redefinedVersionsCount++;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
error = t;
|
||||
}
|
||||
}
|
||||
if (redefinedVersionsCount == 0) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (redefinedVersionsCount < vmClasses.size()) {
|
||||
myPartiallyRedefinedClassesCount++;
|
||||
}
|
||||
myProcessedClassesCount++;
|
||||
}
|
||||
|
||||
private void processChunk() throws Throwable {
|
||||
// reload this portion of classes and clear the map to free memory
|
||||
try {
|
||||
myVirtualMachineProxy.redefineClasses(myRedefineMap);
|
||||
myProcessedClassesCount += myRedefineMap.size();
|
||||
}
|
||||
finally {
|
||||
myRedefineMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void processPending() throws Throwable {
|
||||
if (myRedefineMap.size() > 0) {
|
||||
processChunk();
|
||||
}
|
||||
}
|
||||
|
||||
public int getProcessedClassesCount() {
|
||||
return myProcessedClassesCount;
|
||||
}
|
||||
|
||||
public int getPartiallyRedefinedClassesCount() {
|
||||
return myPartiallyRedefinedClassesCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
@@ -371,7 +372,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AttachItemActionBase extends AnAction {
|
||||
public abstract class AttachItemActionBase extends DumbAwareAction {
|
||||
private VirtualFile myLastChosen = null;
|
||||
|
||||
protected AttachItemActionBase(String text) {
|
||||
|
||||
@@ -688,7 +688,7 @@ public class GenericsHighlightUtil {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (isUncheckedTypeArgumentConversion(lTypeArg, rTypeArg)) return true;
|
||||
if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, false)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -730,48 +730,6 @@ public class GenericsHighlightUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isUncheckedTypeArgumentConversion (PsiType lTypeArg, PsiType rTypeArg) {
|
||||
if (lTypeArg instanceof PsiPrimitiveType || rTypeArg instanceof PsiPrimitiveType) return false;
|
||||
if (lTypeArg.equals(rTypeArg)) return false;
|
||||
if (lTypeArg instanceof PsiCapturedWildcardType) {
|
||||
//ignore capture conversion
|
||||
return isUncheckedTypeArgumentConversion(((PsiCapturedWildcardType)lTypeArg).getWildcard(), rTypeArg);
|
||||
}
|
||||
if (rTypeArg instanceof PsiCapturedWildcardType) {
|
||||
//ignore capture conversion
|
||||
return isUncheckedTypeArgumentConversion(lTypeArg, ((PsiCapturedWildcardType)rTypeArg).getWildcard());
|
||||
}
|
||||
|
||||
if (lTypeArg instanceof PsiWildcardType || rTypeArg instanceof PsiWildcardType) {
|
||||
return !lTypeArg.isAssignableFrom(rTypeArg);
|
||||
}
|
||||
|
||||
if (lTypeArg instanceof PsiArrayType && rTypeArg instanceof PsiArrayType) {
|
||||
return isUncheckedTypeArgumentConversion(((PsiArrayType)rTypeArg).getComponentType(), ((PsiArrayType)lTypeArg).getComponentType());
|
||||
}
|
||||
if (lTypeArg instanceof PsiArrayType || rTypeArg instanceof PsiArrayType) return false;
|
||||
if (lTypeArg instanceof PsiIntersectionType) {
|
||||
for (PsiType type : ((PsiIntersectionType)lTypeArg).getConjuncts()) {
|
||||
if (!isUncheckedTypeArgumentConversion(type, rTypeArg)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!(lTypeArg instanceof PsiClassType)) {
|
||||
LOG.error("left: "+lTypeArg + "; "+lTypeArg.getClass());
|
||||
}
|
||||
if (rTypeArg instanceof PsiIntersectionType) {
|
||||
for (PsiType type : ((PsiIntersectionType)rTypeArg).getConjuncts()) {
|
||||
if (!isUncheckedTypeArgumentConversion(lTypeArg, type)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!(rTypeArg instanceof PsiClassType)) {
|
||||
LOG.error("right :"+rTypeArg + "; "+rTypeArg.getClass());
|
||||
}
|
||||
return ((PsiClassType)lTypeArg).resolve() instanceof PsiTypeParameter ||
|
||||
((PsiClassType)rTypeArg).resolve() instanceof PsiTypeParameter;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) {
|
||||
final PsiParameter parameter = statement.getIterationParameter();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -47,7 +48,10 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.JavaFoldingBuilder");
|
||||
@@ -312,7 +316,9 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar
|
||||
if (importKeyword == null) return null;
|
||||
int startOffset = importKeyword.getTextRange().getEndOffset() + 1;
|
||||
int endOffset = statements[statements.length - 1].getTextRange().getEndOffset();
|
||||
return new TextRange(startOffset, endOffset);
|
||||
if (!hasErrorElementsNearby(element.getContainingFile(), startOffset, endOffset)) {
|
||||
return new TextRange(startOffset, endOffset);
|
||||
}
|
||||
}
|
||||
if (element instanceof PsiDocComment) {
|
||||
return element.getTextRange();
|
||||
@@ -330,6 +336,16 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasErrorElementsNearby(final PsiFile file, int startOffset, int endOffset) {
|
||||
endOffset = CharArrayUtil.shiftForward(file.getText(), endOffset, " \t\n");
|
||||
for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset)) {
|
||||
if (element instanceof PsiErrorElement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TextRange getFileHeader(PsiJavaFile file) {
|
||||
PsiElement first = file.getFirstChild();
|
||||
|
||||
@@ -767,7 +767,14 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
|
||||
int minSpaces = 0;
|
||||
int minLineFeeds = 1;
|
||||
PsiElement psi = myChild1.getPsi();
|
||||
if (mySettings.KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE || psi != null && PsiTreeUtil.hasErrorElements(psi)) {
|
||||
|
||||
// We want to avoid situations like below:
|
||||
// 1. Call 'introduce variable' refactoring for the code like 'System.out.println(1);';
|
||||
// 2. When KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE is on, the output looks like 'int i = 1; System.out.println(i);';
|
||||
// That's why we process the option only during the explicit reformat (directly invoked by an user).
|
||||
if ((mySettings.KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE && FormatterUtil.isFormatterCalledExplicitly())
|
||||
|| psi != null && PsiTreeUtil.hasErrorElements(psi))
|
||||
{
|
||||
minSpaces = 1;
|
||||
minLineFeeds = 0;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ public class TypeConversionUtil {
|
||||
final PsiClass class1 = PsiUtil.resolveClassInType(typeArg1);
|
||||
if (class1 instanceof PsiTypeParameter) {
|
||||
for (PsiType type : class1.getExtendsListTypes()) {
|
||||
if (TypesDistinctProver.provablyDistinct(type, typeArg2)) return false;
|
||||
if (TypesDistinctProver.provablyDistinct(type, typeArg2) && !isAssignable(type, typeArg2)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -746,7 +746,7 @@ public class TypeConversionUtil {
|
||||
|
||||
private static boolean isAssignableToWildcard(PsiWildcardType wildcardType, PsiType right) {
|
||||
if (wildcardType.isSuper()) {
|
||||
return isAssignable(right, wildcardType.getSuperBound());
|
||||
return isAssignable(wildcardType.getSuperBound(), right);
|
||||
}
|
||||
return isAssignable(wildcardType.getExtendsBound(), right);
|
||||
}
|
||||
@@ -859,7 +859,7 @@ public class TypeConversionUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean typesAgree(PsiType typeLeft, PsiType typeRight, boolean allowUncheckedConversion) {
|
||||
public static boolean typesAgree(PsiType typeLeft, PsiType typeRight, boolean allowUncheckedConversion) {
|
||||
if (typeLeft instanceof PsiWildcardType) {
|
||||
final PsiWildcardType leftWildcard = (PsiWildcardType)typeLeft;
|
||||
final PsiType leftBound = leftWildcard.getBound();
|
||||
|
||||
@@ -92,7 +92,10 @@ public class TypesDistinctProver {
|
||||
for (PsiClassType type : parameter.getExtendsListTypes()) {
|
||||
if (!TypeConversionUtil.isAssignable(type, substitutedType1 != null ? substitutedType1 : substitutedType2, false)) return true;
|
||||
}
|
||||
} else if (provablyDistinct(substitutedType1, substitutedType2)) return true;
|
||||
} else {
|
||||
if (provablyDistinct(substitutedType1, substitutedType2)) return true;
|
||||
if (substitutedType1 instanceof PsiWildcardType && !((PsiWildcardType)substitutedType1).isBounded()) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -100,8 +103,8 @@ public class TypesDistinctProver {
|
||||
final PsiClass boundClass1 = classResolveResult1.getElement();
|
||||
final PsiClass boundClass2 = classResolveResult2.getElement();
|
||||
return type2 != null && type1 != null && !type1.equals(type2) &&
|
||||
!InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) &&
|
||||
!InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true);
|
||||
(!InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) ||
|
||||
!InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true));
|
||||
}
|
||||
|
||||
public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2) {
|
||||
|
||||
@@ -172,4 +172,48 @@ class My<T> {
|
||||
public void test() {
|
||||
if (getSuperclass() == List.class);
|
||||
}
|
||||
}
|
||||
|
||||
class IDEA75178 {
|
||||
void test(Set<String> labels) {
|
||||
final Matcher<? super Object> empty = isEmpty();
|
||||
assertThat(labels, empty);
|
||||
assertAlsoThat(empty, labels);
|
||||
}
|
||||
|
||||
public static <T> void assertThat(T actual, Matcher<T> matcher) { throw new AssertionError(actual.toString() + matcher.toString());}
|
||||
public static <T> void assertAlsoThat(Matcher<T> matcher, T actual) { throw new AssertionError(actual.toString() + matcher.toString());}
|
||||
|
||||
public static <T> Matcher<? super T> isEmpty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class Matcher<<warning descr="Type parameter 'T' is never used">T</warning>>{}
|
||||
|
||||
class Foo {}
|
||||
void testComment() {
|
||||
Set<Foo> foos = Collections.emptySet();
|
||||
assertThatComment(foos, hasSize(0));
|
||||
}
|
||||
|
||||
<E> Matcher<? super Collection<? extends E>> hasSize(int size) {return size == 0 ? null : null;}
|
||||
<T> void assertThatComment(T actual, Matcher<? super T> matcher){ throw new AssertionError(actual.toString() + matcher.toString());}
|
||||
}
|
||||
|
||||
class IDEA66750 {
|
||||
public void test() {
|
||||
List<List<String>> data = new ArrayList<List<String>>();
|
||||
List<List<?>> y = <error descr="Inconvertible types; cannot cast 'java.util.List<java.util.List<java.lang.String>>' to 'java.util.List<java.util.List<?>>'">(List<List<?>>)data</error>;
|
||||
System.out.println(y);
|
||||
|
||||
ArrayList<Number> al = <error descr="Inconvertible types; cannot cast 'java.util.ArrayList<java.lang.Integer>' to 'java.util.ArrayList<java.lang.Number>'">(ArrayList<Number>) new ArrayList<Integer>(1)</error>;
|
||||
System.out.println(al);
|
||||
}
|
||||
}
|
||||
|
||||
class IDEA73377 {
|
||||
public Iterator<Map.Entry<Map.Entry<?, ?>, ?>> iterator(Map<?, ?> map) {
|
||||
//noinspection unchecked
|
||||
return <error descr="Inconvertible types; cannot cast 'java.util.Iterator<java.util.Map.Entry<capture<?>,capture<?>>>' to 'java.util.Iterator<java.util.Map.Entry<java.util.Map.Entry<?,?>,?>>'">(Iterator<Map.Entry<Map.Entry<?, ?>, ?>>)map.entrySet().iterator()</error>;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA jdk" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -618,7 +618,7 @@ class Test {
|
||||
doTest(before, toPaste2, expected)
|
||||
}
|
||||
|
||||
def testPlainTextPaste() {
|
||||
void testPlainTextPaste() {
|
||||
def before = '''\
|
||||
line1
|
||||
line2
|
||||
@@ -628,7 +628,7 @@ class Test {
|
||||
def toPaste =
|
||||
'''\
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
line to paste #2\
|
||||
'''
|
||||
|
||||
|
||||
@@ -641,10 +641,33 @@ line to paste #1
|
||||
doTest(before, toPaste, expected, StdFileTypes.PLAIN_TEXT)
|
||||
}
|
||||
|
||||
def testPlainTextPasteWithCompleteReplacement() {
|
||||
void "test plain text when pasted string ends by line feed"() {
|
||||
def before = '''\
|
||||
line1
|
||||
line2
|
||||
<caret>
|
||||
'''
|
||||
|
||||
def toPaste =
|
||||
'''\
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
'''
|
||||
|
||||
def expected = '''\
|
||||
line1
|
||||
line2
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
|
||||
'''
|
||||
doTest(before, toPaste, expected, StdFileTypes.PLAIN_TEXT)
|
||||
}
|
||||
|
||||
void "test plain text when caret is after selection"() {
|
||||
def before = '''\
|
||||
<selection> line1
|
||||
line2</selection>\
|
||||
</selection><caret>\
|
||||
'''
|
||||
|
||||
def toPaste =
|
||||
@@ -655,32 +678,14 @@ line to paste #2
|
||||
|
||||
|
||||
def expected = '''\
|
||||
line1
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
'''
|
||||
doTest(before, toPaste, expected, StdFileTypes.PLAIN_TEXT)
|
||||
}
|
||||
|
||||
def testPlainTextMultilinePasteWithCaretAfterSelection() {
|
||||
def before = '''\
|
||||
<selection> line1</selection><caret>\
|
||||
'''
|
||||
|
||||
def toPaste =
|
||||
'''\
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
'''
|
||||
|
||||
|
||||
def expected = '''\
|
||||
line to paste #1
|
||||
line to paste #2
|
||||
'''
|
||||
doTest(before, toPaste, expected, StdFileTypes.PLAIN_TEXT)
|
||||
}
|
||||
|
||||
def testPlainTextThatStartsByLineFeed() {
|
||||
void testPlainTextThatStartsByLineFeed() {
|
||||
def before = '''\
|
||||
line 1
|
||||
# item1<caret>
|
||||
@@ -715,6 +720,37 @@ line 1
|
||||
doTest(before, toPaste2, expected2, StdFileTypes.PLAIN_TEXT)
|
||||
}
|
||||
|
||||
void "test formatter-based paste that starts with white space"() {
|
||||
def before = '''\
|
||||
class Test {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
void test() {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
def toPaste = '''\
|
||||
int i;
|
||||
int j;\
|
||||
'''
|
||||
|
||||
def expected = '''\
|
||||
class Test {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
void test() {
|
||||
int i;
|
||||
int j;
|
||||
}
|
||||
}
|
||||
'''
|
||||
doTest(before, toPaste, expected)
|
||||
}
|
||||
|
||||
def doTest(String before, toPaste, expected, FileType fileType = StdFileTypes.JAVA) {
|
||||
myFixture.configureByText(fileType, before)
|
||||
|
||||
@@ -732,6 +768,7 @@ line 1
|
||||
finally {
|
||||
settings.REFORMAT_ON_PASTE = old
|
||||
}
|
||||
myFixture.editor.selectionModel.removeSelection()
|
||||
myFixture.checkResult(expected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,32 @@ class Test {
|
||||
assertEquals(2, closureFolds.size())
|
||||
}
|
||||
|
||||
public void "test closure folding doesn't expand when editing inside"() {
|
||||
def text = """\
|
||||
class Test {
|
||||
void test() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(<caret>);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
configure text
|
||||
def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl
|
||||
def closureStartFold = foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable"))
|
||||
assertNotNull closureStartFold
|
||||
assertFalse closureStartFold.expanded
|
||||
assert text.substring(closureStartFold.endOffset).startsWith('System') //one line closure
|
||||
|
||||
myFixture.type('2')
|
||||
myFixture.doHighlighting()
|
||||
closureStartFold = foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable"))
|
||||
assert closureStartFold
|
||||
}
|
||||
|
||||
public void testFindInFolding() {
|
||||
def text = """\
|
||||
class Test {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.resolve
|
||||
|
||||
import com.intellij.openapi.application.ex.PathManagerEx
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void "test prefer current library when navigation from its source"() {
|
||||
def lib = LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManagerEx.getTestDataPath() + "/../../../lib")
|
||||
def nanoJar = lib.children.find { it.name.startsWith("nanoxml") }
|
||||
def nanoSrc = lib.findChild("src").children.find { it.name.startsWith("nanoxml") }
|
||||
|
||||
def jarCopy = myFixture.copyFileToProject(nanoJar.path, 'lib/nanoJar.jar')
|
||||
def srcCopy = myFixture.copyFileToProject(nanoSrc.path, 'lib/nanoSrc.zip')
|
||||
|
||||
PsiTestUtil.addLibrary(myModule, 'nano1', lib.path, ["/$nanoJar.name!/"] as String[], ["/src/$nanoSrc.name!/"] as String[])
|
||||
PsiTestUtil.addLibrary(myModule, 'nano2', jarCopy.parent.path, ["/$jarCopy.name!/"] as String[], ["/$srcCopy.name!/"] as String[])
|
||||
|
||||
def parsers = JavaPsiFacade.getInstance(project).findClasses('net.n3.nanoxml.IXMLParser', GlobalSearchScope.allScope(project))
|
||||
assert parsers.size() == 2
|
||||
|
||||
def file0 = parsers[0].navigationElement.containingFile
|
||||
assert file0.virtualFile.path.startsWith(nanoSrc.path)
|
||||
assert file0.findReferenceAt(file0.text.indexOf('IXMLReader reader')).resolve().navigationElement.containingFile.virtualFile.path.startsWith(nanoSrc.path)
|
||||
|
||||
def file1 = parsers[1].navigationElement.containingFile
|
||||
assert file1.virtualFile.path.startsWith(srcCopy.path)
|
||||
assert file1.findReferenceAt(file1.text.indexOf('IXMLReader reader')).resolve().navigationElement.containingFile.virtualFile.path.startsWith(srcCopy.path)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,4 +9,5 @@ public interface GlobalOptions {
|
||||
String USE_EXTERNAL_JAVAC_OPTION = "use.external.javac.process";
|
||||
String HOSTNAME_OPTION = "localhost.name";
|
||||
String PING_INTERVAL_MS_OPTION = "server.ping.interval";
|
||||
String GENERATE_CLASSPATH_INDEX_OPTION = "generate.classpath.index";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.jetbrains.jps.api;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 3/29/12
|
||||
*/
|
||||
public class SharedThreadPool {
|
||||
public static final ExecutorService INSTANCE = Executors.newCachedThreadPool();
|
||||
public static final AsyncTaskExecutor ASYNC_EXEC = new AsyncTaskExecutor() {
|
||||
@Override
|
||||
public void submit(Runnable runnable) {
|
||||
INSTANCE.submit(runnable);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -30,7 +30,7 @@ public class BuilderRegistry {
|
||||
myTasksExecutor = Executors.newFixedThreadPool(runtime.availableProcessors());
|
||||
runtime.addShutdownHook(new Thread() {
|
||||
public void run() {
|
||||
myTasksExecutor.shutdownNow();
|
||||
myTasksExecutor.shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -70,7 +70,7 @@ public class BuilderRegistry {
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
myTasksExecutor.shutdownNow();
|
||||
myTasksExecutor.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import com.intellij.util.io.MappingFailedException;
|
||||
import com.intellij.util.io.PersistentEnumerator;
|
||||
import org.jetbrains.jps.*;
|
||||
import org.jetbrains.jps.api.CanceledStatus;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
import org.jetbrains.jps.api.RequestFuture;
|
||||
import org.jetbrains.jps.api.SharedThreadPool;
|
||||
import org.jetbrains.jps.incremental.java.ExternalJavacDescriptor;
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder;
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilderLogger;
|
||||
@@ -21,10 +23,13 @@ import org.jetbrains.jps.incremental.storage.SourceToFormMapping;
|
||||
import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.server.ProjectDescriptor;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -35,6 +40,8 @@ public class IncProjectBuilder {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.IncProjectBuilder");
|
||||
|
||||
public static final String COMPILE_SERVER_NAME = "COMPILE SERVER";
|
||||
private static final String CLASSPATH_INDEX_FINE_NAME = "classpath.index";
|
||||
private static final boolean GENERATE_CLASSPATH_INDEX = "true".equals(System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION));
|
||||
|
||||
private final ProjectDescriptor myProjectDescriptor;
|
||||
private final BuilderRegistry myBuilderRegistry;
|
||||
@@ -54,6 +61,7 @@ public class IncProjectBuilder {
|
||||
private float myModulesProcessed = 0.0f;
|
||||
private final float myTotalModulesWork;
|
||||
private final int myTotalModuleLevelBuilderCount;
|
||||
private final List<Future> myAsyncTasks = new ArrayList<Future>();
|
||||
|
||||
public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry, Map<String, String> builderParams, CanceledStatus cs) {
|
||||
myProjectDescriptor = pd;
|
||||
@@ -131,6 +139,15 @@ public class IncProjectBuilder {
|
||||
finally {
|
||||
memWatcher.stop();
|
||||
flushContext(context);
|
||||
// wait for the async tasks
|
||||
for (Future task : myAsyncTasks) {
|
||||
try {
|
||||
task.get();
|
||||
}
|
||||
catch (Throwable th) {
|
||||
LOG.info(th);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,16 +326,18 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void buildChunk(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
private void buildChunk(CompileContext context, final ModuleChunk chunk) throws ProjectBuildException {
|
||||
boolean doneSomething = false;
|
||||
try {
|
||||
context.ensureFSStateInitialized(chunk);
|
||||
if (context.isMake()) {
|
||||
processDeletedPaths(context, chunk);
|
||||
doneSomething |= context.hasRemovedSources();
|
||||
}
|
||||
|
||||
context.onChunkBuildStart(chunk);
|
||||
|
||||
runModuleLevelBuilders(context, chunk);
|
||||
doneSomething = runModuleLevelBuilders(context, chunk);
|
||||
}
|
||||
catch (ProjectBuildException e) {
|
||||
throw e;
|
||||
@@ -343,11 +362,59 @@ public class IncProjectBuilder {
|
||||
}
|
||||
finally {
|
||||
Paths.CHUNK_REMOVED_SOURCES_KEY.set(context, null);
|
||||
if (doneSomething && GENERATE_CLASSPATH_INDEX) {
|
||||
final boolean forTests = context.isCompilingTests();
|
||||
final Future<?> future = SharedThreadPool.INSTANCE.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createClasspathIndex(chunk, forTests);
|
||||
}
|
||||
});
|
||||
myAsyncTasks.add(future);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void createClasspathIndex(final ModuleChunk chunk, boolean forTests) {
|
||||
final Set<File> outputPaths = new LinkedHashSet<File>();
|
||||
for (Module module : chunk.getModules()) {
|
||||
if (forTests) {
|
||||
outputPaths.add(new File(module.getTestOutputPath()));
|
||||
}
|
||||
else {
|
||||
outputPaths.add(new File(module.getOutputPath()));
|
||||
}
|
||||
}
|
||||
for (File outputRoot : outputPaths) {
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outputRoot, CLASSPATH_INDEX_FINE_NAME)));
|
||||
try {
|
||||
writeIndex(writer, outputRoot, "");
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Ignore. Failed to create optional classpath index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeIndex(final BufferedWriter writer, final File file, final String path) throws IOException {
|
||||
writer.write(path);
|
||||
writer.write('\n');
|
||||
final File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File child : files) {
|
||||
writeIndex(writer, child, path + "/" + child.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processDeletedPaths(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
try {
|
||||
// cleanup outputs
|
||||
@@ -420,13 +487,14 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void runModuleLevelBuilders(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
// return true if changed something, false otherwise
|
||||
private boolean runModuleLevelBuilders(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
boolean doneSomething = false;
|
||||
boolean rebuildFromScratchRequested = false;
|
||||
float stageCount = myTotalModuleLevelBuilderCount;
|
||||
final int modulesInChunk = chunk.getModules().size();
|
||||
int buildersPassed = 0;
|
||||
boolean nextPassRequired;
|
||||
|
||||
do {
|
||||
nextPassRequired = false;
|
||||
context.beforeCompileRound(chunk);
|
||||
@@ -448,6 +516,8 @@ public class IncProjectBuilder {
|
||||
}
|
||||
final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk);
|
||||
|
||||
doneSomething |= (buildResult != ModuleLevelBuilder.ExitCode.NOTHING_DONE);
|
||||
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ABORT) {
|
||||
throw new ProjectBuildException("Builder " + builder.getDescription() + " requested build stop");
|
||||
}
|
||||
@@ -492,6 +562,8 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
while (nextPassRequired);
|
||||
|
||||
return doneSomething;
|
||||
}
|
||||
|
||||
private void runProjectLevelBuilders(CompileContext context) throws ProjectBuildException {
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class ModuleLevelBuilder extends Builder {
|
||||
}
|
||||
|
||||
public static enum ExitCode {
|
||||
OK, ABORT, ADDITIONAL_PASS_REQUIRED, CHUNK_REBUILD_REQUIRED
|
||||
NOTHING_DONE, OK, ABORT, ADDITIONAL_PASS_REQUIRED, CHUNK_REBUILD_REQUIRED
|
||||
}
|
||||
|
||||
public abstract ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException;
|
||||
|
||||
@@ -33,8 +33,7 @@ import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.EmptyVisitor;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.*;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ServerSocket;
|
||||
@@ -239,7 +238,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
|
||||
private ExitCode compile(final CompileContext context, ModuleChunk chunk, Collection<File> files, Collection<File> forms)
|
||||
throws Exception {
|
||||
ExitCode exitCode = ExitCode.OK;
|
||||
ExitCode exitCode = ExitCode.NOTHING_DONE;
|
||||
|
||||
final boolean hasSourcesToCompile = !files.isEmpty() || !forms.isEmpty();
|
||||
|
||||
@@ -264,6 +263,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
DELTA_MAPPINGS_CALLBACK_KEY.set(context, delta.getCallback());
|
||||
try {
|
||||
if (hasSourcesToCompile) {
|
||||
exitCode = ExitCode.OK;
|
||||
final Set<File> sourcePath = TEMPORARY_SOURCE_ROOTS_KEY.get(context, Collections.<File>emptySet());
|
||||
|
||||
final String chunkName = getChunkPresentableName(chunk);
|
||||
@@ -868,7 +868,8 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
myContext.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "OutOfMemoryError: insufficient memory"));
|
||||
}
|
||||
else {
|
||||
myContext.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.INFO, line));
|
||||
final BuildMessage.Kind kind = line.toLowerCase(Locale.US).contains("error")? BuildMessage.Kind.ERROR : BuildMessage.Kind.INFO;
|
||||
myContext.processMessage(new CompilerMessage(BUILDER_NAME, kind, line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jps.incremental.resources;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.jps.Module;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
@@ -38,12 +39,14 @@ public class ResourcesBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
try {
|
||||
final ResourcePatterns finalPatterns = patterns;
|
||||
final Ref<Boolean> doneSomething = new Ref<Boolean>(false);
|
||||
context.processFilesToRecompile(chunk, new FileProcessor() {
|
||||
public boolean apply(final Module module, final File file, final String sourceRoot) throws IOException {
|
||||
if (finalPatterns.isResourceFile(file, sourceRoot)) {
|
||||
try {
|
||||
context.processMessage(new ProgressMessage("Copying " + file.getPath()));
|
||||
final String moduleName = module.getName().toLowerCase(Locale.US);
|
||||
doneSomething.set(true);
|
||||
copyResource(context, module, file, sourceRoot, context.getDataManager().getSourceToOutputMap(moduleName, context.isCompilingTests()));
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -56,7 +59,7 @@ public class ResourcesBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
});
|
||||
|
||||
return ExitCode.OK;
|
||||
return doneSomething.get()? ExitCode.OK : ExitCode.NOTHING_DONE;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ProjectBuildException(e.getMessage(), e);
|
||||
|
||||
@@ -2,31 +2,22 @@ package org.jetbrains.jps.javac;
|
||||
|
||||
import org.jboss.netty.channel.MessageEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.api.AsyncTaskExecutor;
|
||||
import org.jetbrains.jps.api.RequestFuture;
|
||||
import org.jetbrains.jps.api.SharedThreadPool;
|
||||
import org.jetbrains.jps.client.SimpleProtobufClient;
|
||||
import org.jetbrains.jps.client.UUIDGetter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 1/22/12
|
||||
*/
|
||||
public class JavacServerClient extends SimpleProtobufClient<JavacServerResponseHandler>{
|
||||
private static final ExecutorService ourExecutors = Executors.newCachedThreadPool();
|
||||
private static final AsyncTaskExecutor ASYNC_EXEC = new AsyncTaskExecutor() {
|
||||
@Override
|
||||
public void submit(Runnable runnable) {
|
||||
ourExecutors.submit(runnable);
|
||||
}
|
||||
};
|
||||
|
||||
public JavacServerClient() {
|
||||
super(JavacRemoteProto.Message.getDefaultInstance(), ASYNC_EXEC, new UUIDGetter() {
|
||||
super(JavacRemoteProto.Message.getDefaultInstance(), SharedThreadPool.ASYNC_EXEC, new UUIDGetter() {
|
||||
@NotNull
|
||||
public UUID getSessionUUID(@NotNull MessageEvent e) {
|
||||
final JavacRemoteProto.Message message = (JavacRemoteProto.Message)e.getMessage();
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 978 B After Width: | Height: | Size: 997 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -35,7 +35,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class LineMarkerInfo<T extends PsiElement> {
|
||||
private final Icon myIcon;
|
||||
protected final Icon myIcon;
|
||||
private final WeakReference<T> elementRef;
|
||||
public final int startOffset;
|
||||
public final int endOffset;
|
||||
@@ -157,7 +157,7 @@ public class LineMarkerInfo<T extends PsiElement> {
|
||||
return myInfo.myIconAlignment;
|
||||
}
|
||||
|
||||
private boolean looksTheSameAs(@NotNull LineMarkerGutterIconRenderer renderer) {
|
||||
protected boolean looksTheSameAs(@NotNull LineMarkerGutterIconRenderer renderer) {
|
||||
return
|
||||
myInfo.getElement() != null &&
|
||||
renderer.myInfo.getElement() != null &&
|
||||
|
||||
@@ -60,4 +60,27 @@ public class RelatedItemLineMarkerInfo<T extends PsiElement> extends LineMarkerI
|
||||
public Collection<? extends GotoRelatedItem> createGotoRelatedItems() {
|
||||
return myTargets.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GutterIconRenderer createGutterRenderer() {
|
||||
if (myIcon == null) return null;
|
||||
return new RelatedItemLineMarkerGutterIconRenderer<T>(this);
|
||||
}
|
||||
|
||||
private static class RelatedItemLineMarkerGutterIconRenderer<T extends PsiElement> extends LineMarkerGutterIconRenderer<T> {
|
||||
public RelatedItemLineMarkerGutterIconRenderer(final RelatedItemLineMarkerInfo<T> markerInfo) {
|
||||
super(markerInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean looksTheSameAs(@NotNull LineMarkerGutterIconRenderer renderer) {
|
||||
if (!(renderer instanceof RelatedItemLineMarkerGutterIconRenderer) || !super.looksTheSameAs(renderer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final RelatedItemLineMarkerInfo<?> markerInfo = (RelatedItemLineMarkerInfo<?>)getLineMarkerInfo();
|
||||
final RelatedItemLineMarkerInfo<?> otherInfo = (RelatedItemLineMarkerInfo<?>)renderer.getLineMarkerInfo();
|
||||
return markerInfo.myTargets.equals(otherInfo.myTargets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -379,7 +379,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser
|
||||
// Algorithm: the main idea is to process the first line of the pasted block, adjust its indent if necessary, calculate indent
|
||||
// adjustment string and apply to each line of the pasted block starting from the second one.
|
||||
//
|
||||
// We differentiate three possible states here:
|
||||
// We differentiate the following possible states here:
|
||||
// --- pasted block doesn't start new line, i.e. there are non-white space symbols before it at the first line.
|
||||
// Example:
|
||||
// old content [pasted line 1
|
||||
@@ -460,7 +460,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser
|
||||
|
||||
final int i = CharArrayUtil.shiftBackward(chars, startOffset - 1, " \t");
|
||||
|
||||
// Handle situation when pasted block doesn't start new line.
|
||||
// Handle a situation when pasted block doesn't start a new line.
|
||||
if (chars.charAt(startOffset) != '\n' && i > 0 && chars.charAt(i) != '\n') {
|
||||
int firstNonWsOffset = CharArrayUtil.shiftForward(chars, firstLineStart, " \t");
|
||||
if (firstNonWsOffset > firstLineStart) {
|
||||
@@ -550,7 +550,7 @@ public class PasteHandler extends EditorActionHandler implements EditorTextInser
|
||||
}
|
||||
}
|
||||
else {
|
||||
CharSequence toInsert = chars.subSequence(anchorLineStart, j + diff);
|
||||
CharSequence toInsert = chars.subSequence(anchorLineStart, diff + startOffset);
|
||||
for (int line = anchorLine + 1; line <= lastLine; line++) {
|
||||
document.insertString(document.getLineStartOffset(line), toInsert);
|
||||
}
|
||||
|
||||
@@ -131,7 +131,6 @@ class MoverWrapper {
|
||||
}
|
||||
});
|
||||
}
|
||||
CodeFoldingManager.getInstance(project).allowFoldingOnCaretLine(editor);
|
||||
|
||||
if (hasSelection) {
|
||||
restoreSelection(editor, selectionStart, selectionEnd, start, myInfo.range2.getStartOffset());
|
||||
|
||||
@@ -50,14 +50,4 @@ public abstract class CodeFoldingManager {
|
||||
|
||||
public abstract void releaseFoldings(Editor editor);
|
||||
public abstract void buildInitialFoldings(Editor editor);
|
||||
|
||||
/**
|
||||
* Asks do not perform automatic expansion of fold region that is located on the caret line during the next fold regions update.
|
||||
* <p/>
|
||||
* This method is necessary because fold regions that are located on caret line are automatically expanded to prevent problem
|
||||
* from IDEA-64687. However, we don't want such an expansion when we, for example, move method up or down.
|
||||
*
|
||||
* @param editor target editor
|
||||
*/
|
||||
public abstract void allowFoldingOnCaretLine(@NotNull Editor editor);
|
||||
}
|
||||
|
||||
@@ -331,9 +331,4 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
|
||||
document.putUserData(FOLDING_STATE_INFO_IN_DOCUMENT_KEY, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allowFoldingOnCaretLine(@NotNull Editor editor) {
|
||||
editor.putUserData(UpdateFoldRegionsOperation.ALLOW_FOLDING_ON_CARET_LINE_KEY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,12 @@ package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.FoldingGroup;
|
||||
import com.intellij.openapi.editor.ex.FoldingModelEx;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -43,9 +41,6 @@ import static com.intellij.util.containers.CollectionFactory.newTroveMap;
|
||||
* @author cdr
|
||||
*/
|
||||
class UpdateFoldRegionsOperation implements Runnable {
|
||||
|
||||
static final Key<Boolean> ALLOW_FOLDING_ON_CARET_LINE_KEY = Key.create("AllowFoldingOnCaretLine.KEY");
|
||||
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final PsiFile myFile;
|
||||
@@ -80,9 +75,6 @@ class UpdateFoldRegionsOperation implements Runnable {
|
||||
List<FoldRegion> newRegions = addNewRegions(info, foldingModel, rangeToExpandStatusMap, shouldExpand, groupExpand);
|
||||
|
||||
applyExpandStatus(newRegions, shouldExpand, groupExpand);
|
||||
|
||||
// Reset the key.
|
||||
myEditor.putUserData(ALLOW_FOLDING_ON_CARET_LINE_KEY, false);
|
||||
}
|
||||
|
||||
private static void applyExpandStatus(@NotNull List<FoldRegion> newRegions,
|
||||
@@ -147,24 +139,9 @@ class UpdateFoldRegionsOperation implements Runnable {
|
||||
// Considering that this code is executed only on initial fold regions construction on editor opening.
|
||||
return !FoldingPolicy.isCollapseByDefault(element);
|
||||
}
|
||||
boolean caretInside;
|
||||
if (myEditor.getUserData(ALLOW_FOLDING_ON_CARET_LINE_KEY) == Boolean.TRUE) {
|
||||
caretInside = FoldingUtil.caretInsideRange(myEditor, range);
|
||||
}
|
||||
else {
|
||||
final Document document = myEditor.getDocument();
|
||||
final int firstLine = document.getLineNumber(range.getStartOffset());
|
||||
final int lastLine = document.getLineNumber(range.getEndOffset());
|
||||
int caretOffset = myEditor.getCaretModel().getOffset();
|
||||
if (caretOffset > myEditor.getDocument().getTextLength()) {
|
||||
return false;
|
||||
}
|
||||
final int currentLine = document.getLineNumber(caretOffset);
|
||||
caretInside = firstLine <= currentLine && currentLine <= lastLine;
|
||||
}
|
||||
|
||||
final Boolean oldStatus = rangeToExpandStatusMap.get(range);
|
||||
return oldStatus == null || caretInside || oldStatus.booleanValue();
|
||||
return oldStatus == null || FoldingUtil.caretInsideRange(myEditor, range) || oldStatus.booleanValue();
|
||||
}
|
||||
|
||||
private void removeInvalidRegions(@NotNull EditorFoldingInfo info,
|
||||
|
||||
@@ -206,6 +206,10 @@ public class GlobalInspectionContextImpl extends UserDataHolderBase implements G
|
||||
|
||||
myContent.setDisposer(myView);
|
||||
|
||||
ContentManager contentManager = getContentManager();
|
||||
contentManager.addContent(myContent);
|
||||
contentManager.setSelectedContent(myContent);
|
||||
|
||||
ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.INSPECTION).activate(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
|
||||
private final JPanel myPanel = new JPanel(new MyLayout());
|
||||
|
||||
private String myTitle;
|
||||
@Nullable
|
||||
private String myPrompt = "> ";
|
||||
private final LightVirtualFile myHistoryFile;
|
||||
private Editor myCurrentEditor;
|
||||
@@ -316,11 +317,12 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
|
||||
return myHistoryFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPrompt() {
|
||||
return myPrompt;
|
||||
}
|
||||
|
||||
public void setPrompt(String prompt) {
|
||||
public void setPrompt(@Nullable String prompt) {
|
||||
// always add space to the prompt otherwise it may look ugly
|
||||
myPrompt = prompt != null && !prompt.endsWith(" ") ? prompt + " " : prompt;
|
||||
setPromptInner(myPrompt);
|
||||
@@ -435,8 +437,10 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
|
||||
protected String addTextRangeToHistory(TextRange textRange, final EditorEx consoleEditor, boolean preserveMarkup) {
|
||||
final Document history = myHistoryViewer.getDocument();
|
||||
final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
|
||||
appendToHistoryDocument(history, myPrompt);
|
||||
markupModel.addRangeHighlighter(history.getTextLength() - myPrompt.length(), history.getTextLength(), HighlighterLayer.SYNTAX,
|
||||
if (myPrompt != null) {
|
||||
appendToHistoryDocument(history, myPrompt);
|
||||
}
|
||||
markupModel.addRangeHighlighter(history.getTextLength() - StringUtil.length(myPrompt), history.getTextLength(), HighlighterLayer.SYNTAX,
|
||||
ConsoleViewContentType.USER_INPUT.getAttributes(),
|
||||
HighlighterTargetArea.EXACT_RANGE);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.formatting;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
@@ -34,7 +33,6 @@ import com.intellij.psi.formatter.PsiBasedFormattingModel;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.SequentialTask;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -98,7 +96,7 @@ public class FormatterImpl extends FormatterEx
|
||||
|
||||
@Override
|
||||
public void setProgressTask(@NotNull FormattingProgressTask progressIndicator) {
|
||||
if (!FormatterUtil.FORMATTER_ACTION_NAMES.contains(CommandProcessor.getInstance().getCurrentCommandName())) {
|
||||
if (!FormatterUtil.isFormatterCalledExplicitly()) {
|
||||
return;
|
||||
}
|
||||
myProgressTask.set(progressIndicator);
|
||||
@@ -694,7 +692,7 @@ public class FormatterImpl extends FormatterEx
|
||||
final boolean keepLineBreaksFlag,
|
||||
final int keepLineBreaks,
|
||||
final boolean keepFirstColumn, int prefLineFeeds) {
|
||||
synchronized(this) {
|
||||
synchronized(ourSharedSpacing) {
|
||||
ourSharedSpacing.init(minSpaces, maxSpaces, minLineFeeds, readOnly, safe, keepLineBreaksFlag, keepLineBreaks, keepFirstColumn, prefLineFeeds);
|
||||
SpacingImpl spacing = ourSharedProperties.get(ourSharedSpacing);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -39,11 +40,9 @@ import java.util.Set;
|
||||
public class LibraryRuntimeClasspathScope extends GlobalSearchScope {
|
||||
private final ProjectFileIndex myIndex;
|
||||
private final LinkedHashSet<VirtualFile> myEntries = new LinkedHashSet<VirtualFile>();
|
||||
private final List<Module> myModules;
|
||||
|
||||
public LibraryRuntimeClasspathScope(final Project project, final List<Module> modules) {
|
||||
super(project);
|
||||
myModules = modules;
|
||||
myIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
final Set<Sdk> processedSdk = new THashSet<Sdk>();
|
||||
final Set<Library> processedLibraries = new THashSet<Library>();
|
||||
@@ -63,8 +62,14 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope {
|
||||
}
|
||||
}
|
||||
|
||||
public LibraryRuntimeClasspathScope(Project project, LibraryOrderEntry entry) {
|
||||
super(project);
|
||||
myIndex = ProjectRootManager.getInstance(project).getFileIndex();
|
||||
Collections.addAll(myEntries, entry.getRootFiles(OrderRootType.CLASSES));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myModules.hashCode();
|
||||
return myEntries.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@@ -72,7 +77,7 @@ public class LibraryRuntimeClasspathScope extends GlobalSearchScope {
|
||||
if (object == null || object.getClass() != LibraryRuntimeClasspathScope.class) return false;
|
||||
|
||||
final LibraryRuntimeClasspathScope that = (LibraryRuntimeClasspathScope)object;
|
||||
return that.myModules.equals(myModules);
|
||||
return that.myEntries.equals(myEntries);
|
||||
}
|
||||
|
||||
private void buildEntries(@NotNull final Module module,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.actions.ReformatAndOptimizeImportsProcessor;
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor;
|
||||
import com.intellij.lang.ASTFactory;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.TokenType;
|
||||
@@ -292,7 +293,11 @@ public class FormatterUtil {
|
||||
private static ASTNode findPreviousWhiteSpace(final ASTNode leafElement, final IElementType whiteSpaceTokenType) {
|
||||
final int offset = leafElement.getTextRange().getStartOffset() - 1;
|
||||
if (offset < 0) return null;
|
||||
final PsiElement found = SourceTreeToPsiMap.treeElementToPsi(leafElement).getContainingFile().findElementAt(offset);
|
||||
final PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(leafElement);
|
||||
if (psiElement == null) {
|
||||
return null;
|
||||
}
|
||||
final PsiElement found = psiElement.getContainingFile().findElementAt(offset);
|
||||
if (found == null) return null;
|
||||
final ASTNode treeElement = found.getNode();
|
||||
if (treeElement != null && treeElement.getElementType() == whiteSpaceTokenType) return treeElement;
|
||||
@@ -357,6 +362,9 @@ public class FormatterUtil {
|
||||
|
||||
public static void replaceLastWhiteSpace(final ASTNode astNode, final String whiteSpace, final TextRange textRange) {
|
||||
ASTNode lastWS = TreeUtil.findLastLeaf(astNode);
|
||||
if (lastWS == null) {
|
||||
return;
|
||||
}
|
||||
if (lastWS.getElementType() != TokenType.WHITE_SPACE) {
|
||||
lastWS = null;
|
||||
}
|
||||
@@ -381,4 +389,11 @@ public class FormatterUtil {
|
||||
treeParent.replaceChild(lastWS, whiteSpaceElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> explicitly called 'reformat' is in progress at the moment; <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean isFormatterCalledExplicitly() {
|
||||
return FORMATTER_ACTION_NAMES.contains(CommandProcessor.getInstance().getCurrentCommandName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.psi.impl.file.impl;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.impl.scopes.LibraryRuntimeClasspathScope;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.*;
|
||||
@@ -25,6 +26,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiManagerImpl;
|
||||
import com.intellij.psi.impl.ResolveScopeManager;
|
||||
import com.intellij.psi.impl.source.resolve.FileContextUtil;
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
@@ -91,6 +93,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
|
||||
List<Module> modulesLibraryUsedIn = new ArrayList<Module>();
|
||||
List<OrderEntry> orderEntries = projectFileIndex.getOrderEntriesForFile(vFile);
|
||||
|
||||
LibraryOrderEntry lib = null;
|
||||
for (OrderEntry entry : orderEntries) {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
@@ -98,12 +101,32 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
|
||||
return ((ProjectRootManagerEx)myProjectRootManager).getScopeForJdk((JdkOrderEntry)entry);
|
||||
}
|
||||
|
||||
if (entry instanceof LibraryOrderEntry || entry instanceof ModuleOrderEntry) {
|
||||
if (entry instanceof LibraryOrderEntry) {
|
||||
lib = (LibraryOrderEntry)entry;
|
||||
modulesLibraryUsedIn.add(entry.getOwnerModule());
|
||||
}
|
||||
else if (entry instanceof ModuleOrderEntry) {
|
||||
modulesLibraryUsedIn.add(entry.getOwnerModule());
|
||||
}
|
||||
}
|
||||
|
||||
return ((ProjectRootManagerEx)myProjectRootManager).getScopeForLibraryUsedIn(modulesLibraryUsedIn);
|
||||
GlobalSearchScope allCandidates = ((ProjectRootManagerEx)myProjectRootManager).getScopeForLibraryUsedIn(modulesLibraryUsedIn);
|
||||
if (lib != null) {
|
||||
final LibraryRuntimeClasspathScope preferred = new LibraryRuntimeClasspathScope(myProject, lib);
|
||||
// prefer current library
|
||||
return new DelegatingGlobalSearchScope(allCandidates, preferred) {
|
||||
@Override
|
||||
public int compare(VirtualFile file1, VirtualFile file2) {
|
||||
boolean c1 = preferred.contains(file1);
|
||||
boolean c2 = preferred.contains(file2);
|
||||
if (c1 && !c2) return 1;
|
||||
if (c2 && !c1) return -1;
|
||||
|
||||
return super.compare(file1, file2);
|
||||
}
|
||||
};
|
||||
}
|
||||
return allCandidates;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.awt.*;
|
||||
public class HintUtil {
|
||||
public static final Color INFORMATION_COLOR = new Color(253, 254, 226);
|
||||
public static final Color QUESTION_COLOR = new Color(181, 208, 251);
|
||||
private static final Color ERROR_COLOR = new Color(255, 220, 220);
|
||||
public static final Color ERROR_COLOR = new Color(255, 220, 220);
|
||||
|
||||
private static final Icon INFORMATION_ICON = null;
|
||||
private static final Icon QUESTION_ICON = IconLoader.getIcon("/actions/help.png");
|
||||
@@ -91,7 +91,7 @@ public class HintUtil {
|
||||
}
|
||||
|
||||
public static JComponent createInformationLabel(final SimpleColoredText text, final Icon icon) {
|
||||
SimpleColoredComponent highlighted = new SimpleColoredComponent ();
|
||||
SimpleColoredComponent highlighted = new SimpleColoredComponent();
|
||||
|
||||
highlighted.setIcon(icon);
|
||||
highlighted.setBackground(INFORMATION_COLOR);
|
||||
@@ -219,6 +219,5 @@ public class HintUtil {
|
||||
public String toString() {
|
||||
return "Hint: text='" + (myPane != null ? myPane.getText() : "") + "'";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -75,6 +76,8 @@ import static java.awt.event.KeyEvent.*;
|
||||
@SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod", "SSBasedInspection"})
|
||||
public class Switcher extends AnAction implements DumbAware {
|
||||
private static volatile SwitcherPanel SWITCHER = null;
|
||||
private static final Icon PIN_ON = IconLoader.getIcon("/general/autohideOn.png");
|
||||
private static final Icon PIN_OFF = IconLoader.getIcon("/general/autohideOff.png");
|
||||
private static final Color BORDER_COLOR = Gray._135;
|
||||
private static final Color SEPARATOR_COLOR = BORDER_COLOR.brighter();
|
||||
@NonNls private static final String SWITCHER_FEATURE_ID = "switcher";
|
||||
@@ -189,7 +192,7 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
addKeyListener(this);
|
||||
setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
setBackground(Color.WHITE);
|
||||
pathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
pathLabel.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
|
||||
final Font font = pathLabel.getFont();
|
||||
pathLabel.setFont(font.deriveFont((float)10));
|
||||
@@ -204,7 +207,19 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
};
|
||||
|
||||
descriptions.setBorder(BorderFactory.createEmptyBorder(1, 4, 1, 4));
|
||||
descriptions.add(pathLabel);
|
||||
descriptions.add(pathLabel, BorderLayout.CENTER);
|
||||
final JLabel pinLabel = new JLabel(isPinnedMode() ? PIN_ON : PIN_OFF);
|
||||
pinLabel.setToolTipText(isPinnedMode() ? "Pinned mode" : "Floating mode");
|
||||
pinLabel.setBorder(IdeBorderFactory.createEmptyBorder(0, 10, 0, 0));
|
||||
descriptions.add(pinLabel, BorderLayout.EAST);
|
||||
pinLabel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE = !UISettings.getInstance().HIDE_SWITCHER_ON_CONTROL_RELEASE;
|
||||
pinLabel.setIcon(isPinnedMode() ? PIN_ON : PIN_OFF);
|
||||
pinLabel.setToolTipText(isPinnedMode() ? "Pinned mode" : "Floating mode");
|
||||
}
|
||||
});
|
||||
twManager = ToolWindowManager.getInstance(project);
|
||||
final DefaultListModel twModel = new DefaultListModel();
|
||||
for (String id : twManager.getToolWindowIds()) {
|
||||
@@ -285,6 +300,7 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
final VirtualFile[] recentFiles = ArrayUtil.reverseArray(EditorHistoryManager.getInstance(project).getFiles());
|
||||
final int maxFiles = Math.max(editors.size(), recentFiles.length);
|
||||
final int len = isPinnedMode() ? maxFiles : Math.min(toolWindows.getModel().getSize(), maxFiles);
|
||||
boolean firstRecentMarked = false;
|
||||
for (int i = 0; i < len; i++) {
|
||||
final FileInfo info = new FileInfo(recentFiles[i], null);
|
||||
boolean add = true;
|
||||
@@ -298,6 +314,10 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
}
|
||||
if (add) {
|
||||
filesData.add(info);
|
||||
if (!firstRecentMarked) {
|
||||
firstRecentMarked = true;
|
||||
info.isSeparator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (editors.size() == 1 && (filesData.isEmpty() || !editors.get(0).getFirst().equals(filesData.get(0).getFirst()))) {
|
||||
@@ -743,6 +763,7 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
public SwitcherSpeedSearch() {
|
||||
super(SwitcherPanel.this);
|
||||
addChangeListener(this);
|
||||
setComparator(new SpeedSearchComparator(false, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -805,6 +826,7 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
private final Project myProject;
|
||||
private final SpeedSearchBase mySearch;
|
||||
private boolean hide = false;
|
||||
private boolean separator = false;
|
||||
|
||||
public VirtualFilesRenderer(Project project, SpeedSearchBase search) {
|
||||
myProject = project;
|
||||
@@ -817,10 +839,12 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
final VirtualFile virtualFile = ((FileInfo)value).first;
|
||||
final String name = virtualFile.getPresentableName();
|
||||
setIcon(IconUtil.getIcon(virtualFile, Iconable.ICON_FLAG_READ_STATUS, myProject));
|
||||
separator = ((FileInfo)value).isSeparator;
|
||||
|
||||
if ( mySearch != null && mySearch.isPopupActive()) {
|
||||
hide = mySearch.matchingFragments(name) == null && !StringUtil.isEmpty(mySearch.getEnteredPrefix());
|
||||
}
|
||||
|
||||
final FileStatus fileStatus = FileStatusManager.getInstance(myProject).getStatus(virtualFile);
|
||||
final TextAttributes attributes = new TextAttributes(fileStatus.getColor(), null, null, EffectType.LINE_UNDERSCORE, Font.PLAIN);
|
||||
append(name, SimpleTextAttributes.fromTextAttributes(attributes));
|
||||
@@ -835,10 +859,14 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
}
|
||||
super.doPaint(g);
|
||||
config.restore();
|
||||
if (separator) {
|
||||
UIUtil.drawDottedLine(g, 0, 0, getWidth(), 0, Color.WHITE, Color.BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileInfo extends Pair<VirtualFile, EditorWindow> {
|
||||
boolean isSeparator = false;
|
||||
public FileInfo(VirtualFile first, EditorWindow second) {
|
||||
super(first, second);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.net.IOExceptionDialog;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.io.IOException;
|
||||
@@ -157,7 +158,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
if (needToRestart) {
|
||||
notifyPluginsWereInstalled();
|
||||
notifyPluginsWereInstalled(list.size() == 1 ? list.get(0).getName() : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +257,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
}
|
||||
}
|
||||
|
||||
private static void notifyPluginsWereInstalled() {
|
||||
private static void notifyPluginsWereInstalled(@Nullable String pluginName) {
|
||||
final ApplicationEx app = ApplicationManagerEx.getApplicationEx();
|
||||
final boolean restartCapable = app.isRestartCapable();
|
||||
String message = "<html>";
|
||||
@@ -265,7 +266,8 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
message += "<br><a href=";
|
||||
message += restartCapable ? "\"restart\">Restart now" : "\"shutdown\">Shutdown";
|
||||
message += "</a></html>";
|
||||
Notifications.Bus.notify(new Notification(IdeBundle.message("title.plugin.error"), IdeBundle.message("title.plugin.error"),
|
||||
Notifications.Bus.notify(new Notification("Plugins Lifecycle Group",
|
||||
pluginName != null ? "Plugin \'" + pluginName + "\' was successfully installed" : "Plugins were installed",
|
||||
message, NotificationType.INFORMATION, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
|
||||
@@ -53,15 +53,17 @@ public class DetectedPluginsPanel extends OrderPanel<PluginDownloader> {
|
||||
final int row,
|
||||
final int column) {
|
||||
final PluginDownloader downloader = (PluginDownloader)value;
|
||||
append(downloader.getPluginName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
final IdeaPluginDescriptor ideaPluginDescriptor = PluginManager.getPlugin(PluginId.getId(downloader.getPluginId()));
|
||||
final String loadedVersion = downloader.getPluginVersion();
|
||||
if (loadedVersion != null || (ideaPluginDescriptor != null && ideaPluginDescriptor.getVersion() != null)) {
|
||||
final String installedVersion = ideaPluginDescriptor != null && ideaPluginDescriptor.getVersion() != null
|
||||
? "v. " + ideaPluginDescriptor.getVersion() + (loadedVersion != null ? " -> " : "")
|
||||
: "";
|
||||
final String availableVersion = loadedVersion != null ? loadedVersion : "";
|
||||
append(" (" + installedVersion + availableVersion + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
if (downloader != null) {
|
||||
append(downloader.getPluginName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
final IdeaPluginDescriptor ideaPluginDescriptor = PluginManager.getPlugin(PluginId.getId(downloader.getPluginId()));
|
||||
final String loadedVersion = downloader.getPluginVersion();
|
||||
if (loadedVersion != null || (ideaPluginDescriptor != null && ideaPluginDescriptor.getVersion() != null)) {
|
||||
final String installedVersion = ideaPluginDescriptor != null && ideaPluginDescriptor.getVersion() != null
|
||||
? "v. " + ideaPluginDescriptor.getVersion() + (loadedVersion != null ? " -> " : "")
|
||||
: "";
|
||||
final String availableVersion = loadedVersion != null ? loadedVersion : "";
|
||||
append(" (" + installedVersion + availableVersion + ")", SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="eecc0" binding="myPlaceHolder" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<grid id="eecc0" binding="myPlaceHolder" layout-manager="GridBagLayout">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
|
||||
@@ -30,10 +30,7 @@ import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
@@ -278,4 +275,26 @@ import java.util.Collection;
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public static void addLibrary(final Module module,
|
||||
final String libName, final String libDir,
|
||||
final String[] classRoots,
|
||||
final String[] sourceRoots) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
final String parentUrl = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, libDir);
|
||||
final Library library = model.getModuleLibraryTable().createLibrary(libName);
|
||||
final Library.ModifiableModel libModifiableModel = library.getModifiableModel();
|
||||
for (String classRoot : classRoots) {
|
||||
libModifiableModel.addRoot(parentUrl + classRoot, OrderRootType.CLASSES);
|
||||
}
|
||||
for (String sourceRoot : sourceRoots) {
|
||||
libModifiableModel.addRoot(parentUrl + sourceRoot, OrderRootType.SOURCES);
|
||||
}
|
||||
libModifiableModel.commit();
|
||||
model.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -25,6 +25,7 @@ import com.intellij.android.designer.propertyTable.editors.ResourceDialog;
|
||||
import com.intellij.designer.model.MetaManager;
|
||||
import com.intellij.designer.model.MetaModel;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.designer.model.RadLayout;
|
||||
import com.intellij.designer.propertyTable.Property;
|
||||
import com.intellij.designer.propertyTable.PropertyTable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -47,6 +48,10 @@ import java.util.*;
|
||||
public class PropertyParser {
|
||||
public static final String KEY = "PROPERTY_PARSER";
|
||||
|
||||
private static final String[] DEFAULT_LAYOUT_PARAMS = {"ViewGroup_Layout"};
|
||||
private static final String LAYOUT_PREFIX = "layout_";
|
||||
private static final String LAYOUT_MARGIN_PREFIX = "layout_margin";
|
||||
|
||||
private final Module myModule;
|
||||
private MetaManager myMetaManager;
|
||||
private AttributeDefinitions myDefinitions;
|
||||
@@ -90,23 +95,45 @@ public class PropertyParser {
|
||||
if (componentClass.getName().equals("com.android.layoutlib.bridge.MockView")) {
|
||||
componentClass = myClassLoader.loadClass("android.view.View");
|
||||
}
|
||||
component.setProperties(load(componentClass, model));
|
||||
component.setProperties(loadWidgetProperties(componentClass, model));
|
||||
}
|
||||
}
|
||||
else {
|
||||
component.setProperties(load(myClassLoader.loadClass(target), model));
|
||||
component.setProperties(loadWidgetProperties(myClassLoader.loadClass(target), model));
|
||||
}
|
||||
|
||||
// TODO: load layout constrain properties
|
||||
RadComponent parent = component.getParent();
|
||||
if (parent != null) {
|
||||
String[] layoutParams = null;
|
||||
RadLayout layout = parent.getLayout();
|
||||
|
||||
if (layout instanceof RadViewLayoutWithData) {
|
||||
layoutParams = ((RadViewLayoutWithData)layout).getLayoutParams();
|
||||
}
|
||||
else if (parent == parent.getRoot()) {
|
||||
layoutParams = DEFAULT_LAYOUT_PARAMS;
|
||||
}
|
||||
|
||||
if (layoutParams != null) {
|
||||
List<Property> properties = loadLayoutProperties(layoutParams, 0);
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
properties = new ArrayList<Property>(properties);
|
||||
properties.addAll(component.getProperties());
|
||||
component.setProperties(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Property> load(Class<?> componentClass, MetaModel model) throws Exception {
|
||||
private List<Property> loadWidgetProperties(Class<?> componentClass, MetaModel model) throws Exception {
|
||||
String component = componentClass.getSimpleName();
|
||||
|
||||
List<Property> properties = myCachedProperties.get(component);
|
||||
|
||||
if (properties == null) {
|
||||
properties = new ArrayList<Property>();
|
||||
myCachedProperties.put(component, properties);
|
||||
|
||||
StyleableDefinition definitions = myDefinitions.getStyleableByName(component);
|
||||
if (definitions != null) {
|
||||
@@ -153,7 +180,8 @@ public class PropertyParser {
|
||||
superComponentClass = myClassLoader.loadClass("android.view.View");
|
||||
}
|
||||
|
||||
List<Property> superProperties = load(superComponentClass, myMetaManager.getModelByTarget(superComponentClass.getName()));
|
||||
List<Property> superProperties = loadWidgetProperties(superComponentClass,
|
||||
myMetaManager.getModelByTarget(superComponentClass.getName()));
|
||||
for (Property superProperty : superProperties) {
|
||||
if (PropertyTable.findProperty(properties, superProperty) == -1) {
|
||||
if (model == null) {
|
||||
@@ -192,8 +220,79 @@ public class PropertyParser {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private List<Property> loadLayoutProperties(String[] components, int index) throws Exception {
|
||||
String component = components[index];
|
||||
|
||||
List<Property> properties = myCachedProperties.get(component);
|
||||
|
||||
if (properties == null) {
|
||||
properties = new ArrayList<Property>();
|
||||
myCachedProperties.put(component, properties);
|
||||
|
||||
StyleableDefinition definitions = myDefinitions.getStyleableByName(component);
|
||||
if (definitions != null) {
|
||||
Property margin = null;
|
||||
|
||||
for (AttributeDefinition definition : definitions.getAttributes()) {
|
||||
String name = definition.getName();
|
||||
boolean important = true;
|
||||
Set<AttributeFormat> formats = definition.getFormats();
|
||||
Property property;
|
||||
|
||||
if (name.startsWith(LAYOUT_MARGIN_PREFIX) && name.length() > LAYOUT_MARGIN_PREFIX.length()) {
|
||||
name = name.substring(LAYOUT_PREFIX.length());
|
||||
important = false;
|
||||
}
|
||||
else if (name.startsWith(LAYOUT_PREFIX)) {
|
||||
name = "layout:" + name.substring(LAYOUT_PREFIX.length());
|
||||
}
|
||||
|
||||
if ("layout:margin".equals(name) && "ViewGroup_MarginLayout".equals(component)) {
|
||||
property = margin = new CompoundProperty(name, definition);
|
||||
}
|
||||
else if (formats.contains(AttributeFormat.Flag)) {
|
||||
property = new FlagProperty(name, definition);
|
||||
}
|
||||
else {
|
||||
property = new AttributeProperty(name, definition);
|
||||
}
|
||||
|
||||
property.setImportant(important);
|
||||
properties.add(property);
|
||||
}
|
||||
|
||||
if (margin != null) {
|
||||
List children = margin.getChildren(null);
|
||||
children.add(PropertyTable.extractProperty(properties, "marginLeft"));
|
||||
children.add(PropertyTable.extractProperty(properties, "marginTop"));
|
||||
children.add(PropertyTable.extractProperty(properties, "marginRight"));
|
||||
children.add(PropertyTable.extractProperty(properties, "marginBottom"));
|
||||
children.add(PropertyTable.extractProperty(properties, "marginStart"));
|
||||
children.add(PropertyTable.extractProperty(properties, "marginEnd"));
|
||||
}
|
||||
}
|
||||
|
||||
if (++index < components.length) {
|
||||
for (Property property : loadLayoutProperties(components, index)) {
|
||||
if (PropertyTable.findProperty(properties, property) == -1) {
|
||||
properties.add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
Collections.sort(properties, new Comparator<Property>() {
|
||||
@Override
|
||||
public int compare(Property p1, Property p2) {
|
||||
return p1.getName().compareTo(p2.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
|
||||
import com.intellij.designer.designSurface.ComponentDecorator;
|
||||
import com.intellij.designer.designSurface.DesignerEditorPanel;
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class RadFrameLayout extends RadViewLayoutWithData {
|
||||
private static final String[] LAYOUT_PARAMS = {"FrameLayout_Layout", "ViewGroup_MarginLayout"};
|
||||
|
||||
@Override
|
||||
public String[] getLayoutParams() {
|
||||
return LAYOUT_PARAMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentDecorator getChildSelectionDecorator(RadComponent component, List<RadComponent> selection) {
|
||||
return super.getChildSelectionDecorator(component, selection); // TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditOperation processChildOperation(OperationContext context) {
|
||||
return super.processChildOperation(context); // TODO: Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSelectionActions(DesignerEditorPanel designer,
|
||||
DefaultActionGroup actionGroup,
|
||||
JComponent shortcuts,
|
||||
List<RadComponent> selection) {
|
||||
super.addSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,14 @@ import java.util.List;
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class RadLinearLayout extends RadViewLayout {
|
||||
public class RadLinearLayout extends RadViewLayoutWithData {
|
||||
private static final String[] LAYOUT_PARAMS = {"LinearLayout_Layout", "ViewGroup_MarginLayout"};
|
||||
|
||||
@Override
|
||||
public String[] getLayoutParams() {
|
||||
return LAYOUT_PARAMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EditOperation processChildOperation(OperationContext context) {
|
||||
if (context.isCreate()) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
|
||||
import com.intellij.designer.designSurface.DesignerEditorPanel;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class RadViewGroupComponent extends RadViewComponent {
|
||||
@Override
|
||||
public void addSelectionActions(DesignerEditorPanel designer,
|
||||
DefaultActionGroup actionGroup,
|
||||
JComponent shortcuts,
|
||||
List<RadComponent> selection) {
|
||||
super.addSelectionActions(designer, actionGroup, shortcuts, selection); // TODO: Auto-generated method stub
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public abstract class RadViewLayoutWithData extends RadViewLayout {
|
||||
public abstract String[] getLayoutParams();
|
||||
}
|
||||
@@ -983,7 +983,7 @@
|
||||
|
||||
<!-- ================= Layouts ================= -->
|
||||
|
||||
<meta model="com.intellij.android.designer.model.RadViewComponent"
|
||||
<meta model="com.intellij.android.designer.model.RadViewGroupComponent"
|
||||
layout="com.intellij.android.designer.model.RadLinearLayout"
|
||||
class="android.widget.LinearLayout"
|
||||
tag="LinearLayout">
|
||||
@@ -1004,6 +1004,26 @@
|
||||
</creation>
|
||||
</meta>
|
||||
|
||||
<meta model="com.intellij.android.designer.model.RadViewGroupComponent"
|
||||
layout="com.intellij.android.designer.model.RadFrameLayout"
|
||||
class="android.widget.FrameLayout"
|
||||
tag="FrameLayout">
|
||||
|
||||
<palette title="FrameLayout" icon="/com/intellij/android/designer/icons/FrameLayout.png"
|
||||
tooltip="FrameLayout is designed to block out an area on the screen to display a single item."/>
|
||||
|
||||
<properties important="foreground foregroundGravity"/>
|
||||
|
||||
<creation>
|
||||
<![CDATA[
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</FrameLayout>
|
||||
]]>
|
||||
</creation>
|
||||
</meta>
|
||||
|
||||
<!-- ================= Palette ================= -->
|
||||
|
||||
<palette>
|
||||
@@ -1061,6 +1081,7 @@
|
||||
<item tag="AdapterViewFlipper"/>
|
||||
</group>
|
||||
<group name="Layouts">
|
||||
<item tag="FrameLayout"/>
|
||||
<item tag="LinearLayout"/>
|
||||
</group>
|
||||
</palette>
|
||||
|
||||
@@ -30,9 +30,9 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleLevelBuilder.ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
public ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
if (context.isCompilingTests() || !AndroidJpsUtil.containsAndroidFacet(chunk) || AndroidJpsUtil.isLightBuild(context)) {
|
||||
return ModuleLevelBuilder.ExitCode.OK;
|
||||
return ExitCode.NOTHING_DONE;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -48,6 +48,7 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
|
||||
final AndroidFileSetStorage storage = new AndroidFileSetStorage(context.getDataManager().getDataStorageRoot(), "libs_packaging");
|
||||
|
||||
try {
|
||||
boolean doneSomething = false;
|
||||
for (Module module : chunk.getModules()) {
|
||||
final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
|
||||
if (facet == null || !facet.isLibrary()) {
|
||||
@@ -82,7 +83,7 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
|
||||
if (subdirs.size() > 0) {
|
||||
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.library.packaging", module.getName())));
|
||||
final File outputJarFile = new File(outputDirectoryForPackagedFiles, AndroidCommonUtils.CLASSES_JAR_FILE_NAME);
|
||||
|
||||
doneSomething = true;
|
||||
try {
|
||||
AndroidCommonUtils.packClassFilesIntoJar(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.toStringArray(subdirs), outputJarFile);
|
||||
storage.update(module.getName(), newState);
|
||||
@@ -94,7 +95,7 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
return success ? ModuleLevelBuilder.ExitCode.OK : ModuleLevelBuilder.ExitCode.ABORT;
|
||||
return success ? (doneSomething? ExitCode.OK : ExitCode.NOTHING_DONE) : ExitCode.ABORT;
|
||||
}
|
||||
finally {
|
||||
storage.close();
|
||||
|
||||
@@ -61,7 +61,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
|
||||
@Override
|
||||
public ModuleLevelBuilder.ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
if (context.isCompilingTests() || !AndroidJpsUtil.containsAndroidFacet(chunk)) {
|
||||
return ModuleLevelBuilder.ExitCode.OK;
|
||||
return ExitCode.NOTHING_DONE;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
public class EclipseLibrariesModificationsTest extends EclipseVarsTest {
|
||||
@@ -38,22 +39,8 @@ public class EclipseLibrariesModificationsTest extends EclipseVarsTest {
|
||||
final Project project = getProject();
|
||||
final String path = project.getBaseDir().getPath() + "/test";
|
||||
final Module module = EclipseClasspathTest.setUpModule(path, project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
final String parentUrl = VirtualFileManager.constructUrl(JarFileSystem.PROTOCOL, model.getContentRoots()[0].getParent().getPath());
|
||||
final Library library = model.getModuleLibraryTable().createLibrary("created");
|
||||
final Library.ModifiableModel libModifiableModel = library.getModifiableModel();
|
||||
for (String classRoot : classRoots) {
|
||||
libModifiableModel.addRoot(parentUrl + classRoot, OrderRootType.CLASSES);
|
||||
}
|
||||
for (String sourceRoot : sourceRoots) {
|
||||
libModifiableModel.addRoot(parentUrl + sourceRoot, OrderRootType.SOURCES);
|
||||
}
|
||||
libModifiableModel.commit();
|
||||
model.commit();
|
||||
}
|
||||
});
|
||||
PsiTestUtil.addLibrary(module, "created", ModuleRootManager.getInstance(module).getContentRoots()[0].getParent().getPath(), classRoots,
|
||||
sourceRoots);
|
||||
|
||||
EclipseClasspathTest.checkModule(project.getBaseDir().getPath() + "/expected", module);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
try {
|
||||
final List<File> toCompile = collectChangedFiles(context, chunk);
|
||||
if (toCompile.isEmpty()) {
|
||||
return ExitCode.OK;
|
||||
return ExitCode.NOTHING_DONE;
|
||||
}
|
||||
|
||||
String moduleOutput = getModuleOutput(context, chunk);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.folding;
|
||||
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.CustomFoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
@@ -194,7 +195,7 @@ public class GroovyFoldingBuilder extends CustomFoldingBuilder implements Groovy
|
||||
int start = first.getTextRange().getStartOffset();
|
||||
int end = marker.getTextRange().getEndOffset();
|
||||
int tail = "import ".length();
|
||||
if (start + tail < end) {
|
||||
if (start + tail < end && !JavaFoldingBuilder.hasErrorElementsNearby(first.getContainingFile(), start, end)) {
|
||||
descriptors.add(new FoldingDescriptor(first.getNode(), new TextRange(start + tail, end)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,25 @@ class GroovyFoldingTest extends LightCodeInsightFixtureTestCase {
|
||||
assert assertNoFolding(myFixture.file.text.indexOf(marker)), marker
|
||||
}
|
||||
|
||||
public void testEditingImports() {
|
||||
configure """
|
||||
import java.util.List
|
||||
import java.util.Map
|
||||
<caret>
|
||||
|
||||
println 'hello'
|
||||
|
||||
class Foo { List a; Map b; }
|
||||
"""
|
||||
|
||||
assert myFixture.editor.foldingModel.getCollapsedRegionAtOffset(10)
|
||||
|
||||
myFixture.type 'import '
|
||||
myFixture.doHighlighting()
|
||||
assert !myFixture.editor.foldingModel.getCollapsedRegionAtOffset(10)
|
||||
}
|
||||
|
||||
|
||||
void testOpenBlock() {
|
||||
configure '''def foo() {print 'a'}
|
||||
def bar() {
|
||||
|
||||
@@ -252,7 +252,7 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
|
||||
@Override
|
||||
public ExecutionResult execute(final Executor executor, @NotNull final ProgramRunner runner) throws ExecutionException {
|
||||
final JUnitProcessHandler handler = createHandler();
|
||||
final JUnitProcessHandler handler = createHandler(executor);
|
||||
final RunnerSettings runnerSettings = getRunnerSettings();
|
||||
JavaRunConfigurationExtensionManager.getInstance().attachExtensionsToProcess(myConfiguration, handler, runnerSettings);
|
||||
final TestProxy unboundOutputRoot = new TestProxy(new RootTestInfo());
|
||||
@@ -360,19 +360,20 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
TestsUIUtil.notifyByBalloon(myProject, model != null ? model.getRoot() : null, consoleProperties);
|
||||
}
|
||||
|
||||
protected JUnitProcessHandler createHandler() throws ExecutionException {
|
||||
appendForkInfo();
|
||||
protected JUnitProcessHandler createHandler(Executor executor) throws ExecutionException {
|
||||
appendForkInfo(executor);
|
||||
return JUnitProcessHandler.runCommandLine(CommandLineBuilder.createFromJavaParameters(myJavaParameters, myProject, true));
|
||||
}
|
||||
|
||||
private void appendForkInfo() throws ExecutionException {
|
||||
private void appendForkInfo(Executor executor) throws ExecutionException {
|
||||
final String forkMode = myConfiguration.getForkMode();
|
||||
if (Comparing.strEqual(forkMode, "none")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (myRunnerSettings.getData() instanceof DebuggingRunnerData) {
|
||||
throw new CantRunException("Debug is disabled in fork mode.<br/>Please change fork mode to <none> to debug.");
|
||||
if (myRunnerSettings.getData() != null) {
|
||||
final String actionName = executor.getActionName();
|
||||
throw new CantRunException(actionName + " is disabled in fork mode.<br/>Please change fork mode to <none> to " + actionName.toLowerCase() + ".");
|
||||
}
|
||||
|
||||
final JavaParameters javaParameters = getJavaParameters();
|
||||
|
||||
@@ -87,8 +87,8 @@ public class TestPackage extends TestObject {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JUnitProcessHandler createHandler() throws ExecutionException {
|
||||
final JUnitProcessHandler handler = super.createHandler();
|
||||
protected JUnitProcessHandler createHandler(Executor executor) throws ExecutionException {
|
||||
final JUnitProcessHandler handler = super.createHandler(executor);
|
||||
final SearchForTestsTask[] tasks = new SearchForTestsTask[1];
|
||||
handler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.intellij.junit4;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.internal.AssumptionViolatedException;
|
||||
import org.junit.internal.builders.JUnit3Builder;
|
||||
import org.junit.internal.requests.ClassRequest;
|
||||
import org.junit.internal.runners.model.EachTestNotifier;
|
||||
import org.junit.runner.Description;
|
||||
@@ -151,7 +150,7 @@ public class JUnit4TestRunnerUtil {
|
||||
}
|
||||
try {
|
||||
if (clazz.getMethod("suite", new Class[0]) != null && !methodName.equals("suite")) {
|
||||
return Request.runner(new JUnit3Builder().runnerForClass(clazz)).filterWith(Description.createTestDescription(clazz, methodName));
|
||||
return Request.classWithoutSuiteMethod(clazz).filterWith(Description.createTestDescription(clazz, methodName));
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.idea.maven.indices.MavenIndicesTestFixture;
|
||||
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class MavenExtensionCompletionAndResolutionTest extends MavenDomWithIndicesTestCase {
|
||||
@@ -70,10 +72,11 @@ public class MavenExtensionCompletionAndResolutionTest extends MavenDomWithIndic
|
||||
|
||||
List<String> actual = getCompletionVariants(myProjectPom);
|
||||
|
||||
if (actual.isEmpty()) {
|
||||
if (!new HashSet<String>(actual).equals(new HashSet<String>(Arrays.asList("maven-compiler-plugin", "maven-war-plugin", "maven-eclipse-plugin", "maven-surefire-plugin")))) {
|
||||
MavenProjectIndicesManager instance = MavenProjectIndicesManager.getInstance(myProject);
|
||||
System.out.println("GetArtifacts: " + instance.getArtifactIds("org.apache.maven.plugins"));
|
||||
System.out.println("Indexes: " + instance.getIndices());
|
||||
throw new AssertionError("GetArtifacts: " + instance.getArtifactIds("org.apache.maven.plugins") + "Indexes: " + instance.getIndices());
|
||||
}
|
||||
|
||||
assertUnorderedElementsAreEqual(actual, "maven-compiler-plugin", "maven-war-plugin", "maven-eclipse-plugin", "maven-surefire-plugin");
|
||||
|
||||
@@ -164,6 +164,7 @@ error.exception.while.reloading=Exception while reloading classes : {0} : {1}
|
||||
status.hotswap.loaded.classes.up.to.date=Loaded classes are up to date. Nothing to reload
|
||||
error.io.error=I/O error
|
||||
status.classes.reloaded={0,number} {0,choice, 0#classes|1#class|2#classes} reloaded
|
||||
status.classes.not.all.versions.reloaded=For {0} of {1} {1,choice, 1#class|2#classes} not all versions were reloaded
|
||||
error.cannot.create.void.value=Cannot create void value
|
||||
warning.range.too.big=Range specified is too big. {0} needs too much resources to perform requested operation. Are you sure you want to continue?
|
||||
title.range.too.big=Range is Too Big
|
||||
|
||||
@@ -17,13 +17,11 @@ package com.intellij.xml.util;
|
||||
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.psi.PsiAnchor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xmlb.JDOMXIncluder;
|
||||
@@ -82,12 +80,7 @@ class InclusionProvider implements CachedValueProvider<PsiElement[]> {
|
||||
final XmlTag[] includeTag = extractXpointer(rootTag, xpointer);
|
||||
PsiElement[] result = new PsiElement[includeTag.length];
|
||||
for (int i = 0; i < includeTag.length; i++) {
|
||||
XmlTag xmlTag = includeTag[i];
|
||||
final PsiElement psiElement = xmlTag.copy();
|
||||
psiElement.putUserData(XmlElement.INCLUDING_ELEMENT, xincludeTag.getParentTag());
|
||||
psiElement.putUserData(XmlUtil.ORIGINAL_ELEMENT, PsiAnchor.create(xmlTag));
|
||||
result[i] = psiElement;
|
||||
//result[i] = new IncludedXmlTag(includeTag[i], xincludeTag.getParentTag());
|
||||
result[i] = new IncludedXmlTag(includeTag[i], xincludeTag.getParentTag());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||