Merge remote 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);
|
||||
|
||||
@@ -1755,7 +1755,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
|
||||
fail();
|
||||
if (myExecutionResult != null || !connectorIsReady.get()) {
|
||||
// propagate exception only in case we succeded to obtain execution result,
|
||||
// otherwise it the error is induced by the fact that there is nothing to debug, and there is no need to show
|
||||
// otherwise if the error is induced by the fact that there is nothing to debug, and there is no need to show
|
||||
// this problem to the user
|
||||
final RunProfile runProfile = state.getRunnerSettings().getRunProfile();
|
||||
if (runProfile != null) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,28 +96,29 @@ public class DebuggerPanelsManager implements ProjectComponent {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public
|
||||
RunContentDescriptor attachVirtualMachine(Executor executor,
|
||||
ProgramRunner runner,
|
||||
ExecutionEnvironment environment,
|
||||
RunProfileState state,
|
||||
RunContentDescriptor reuseContent,
|
||||
RemoteConnection remoteConnection,
|
||||
boolean pollConnection) throws ExecutionException {
|
||||
public RunContentDescriptor attachVirtualMachine(Executor executor,
|
||||
ProgramRunner runner,
|
||||
ExecutionEnvironment environment,
|
||||
RunProfileState state,
|
||||
RunContentDescriptor reuseContent,
|
||||
RemoteConnection remoteConnection,
|
||||
boolean pollConnection) throws ExecutionException {
|
||||
|
||||
final DebuggerSession debuggerSession =
|
||||
DebuggerManagerEx.getInstanceEx(myProject).attachVirtualMachine(executor, runner, (ModuleRunProfile) environment.getRunProfile(), state, remoteConnection, pollConnection);
|
||||
final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(myProject).attachVirtualMachine(
|
||||
executor, runner, (ModuleRunProfile) environment.getRunProfile(), state, remoteConnection, pollConnection
|
||||
);
|
||||
if (debuggerSession == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final DebugProcessImpl debugProcess = debuggerSession.getProcess();
|
||||
if (debugProcess.isDetached() || debugProcess.isDetaching()) {
|
||||
debuggerSession.dispose();
|
||||
return null;
|
||||
}
|
||||
if (state instanceof RemoteState) {
|
||||
// optimization: that way BatchEvaluator will not try to lookup the class file in remote VM
|
||||
// which is an expensive oparation when executed first time
|
||||
// which is an expensive operation when executed first time
|
||||
debugProcess.putUserData(BatchEvaluator.REMOTE_SESSION_KEY, Boolean.TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -128,11 +128,16 @@ public class JavaCharFilter extends CharFilter {
|
||||
|
||||
if (c == '[') return CharFilter.Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
if (c == '<' && o instanceof PsiClass) return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
if (c == '(' && o instanceof PsiClass) {
|
||||
if (PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.NEW).accepts(lookup.getPsiElement())) {
|
||||
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
if (c == '(') {
|
||||
if (o instanceof PsiClass) {
|
||||
if (PsiJavaPatterns.psiElement().afterLeaf(PsiKeyword.NEW).accepts(lookup.getPsiElement())) {
|
||||
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
|
||||
}
|
||||
return Result.HIDE_LOOKUP;
|
||||
}
|
||||
if (o instanceof PsiType) {
|
||||
return Result.HIDE_LOOKUP;
|
||||
}
|
||||
return Result.HIDE_LOOKUP;
|
||||
}
|
||||
if ((c == ',' || c == '=') && o instanceof PsiVariable) {
|
||||
int lookupStart = ((LookupImpl)lookup).getLookupStart();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -24,7 +24,10 @@ import com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
|
||||
import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
@@ -248,7 +251,7 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool
|
||||
PsiParameter parameter = parameters[Math.min(i, parameters.length - 1)];
|
||||
final PsiExpression expression = expressions[i];
|
||||
final PsiType parameterType = substitutor.substitute(parameter.getType());
|
||||
final PsiType expressionType = substitutor.substitute(expression.getType());
|
||||
final PsiType expressionType = expression.getType();
|
||||
if (expressionType != null) {
|
||||
checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myGenerifyFixes);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -151,8 +151,11 @@ public class PsiSubstitutorImpl implements PsiSubstitutor {
|
||||
if (newBound instanceof PsiWildcardType) {
|
||||
return handleBoundComposition(wildcardType, (PsiWildcardType)newBound);
|
||||
}
|
||||
if (newBound instanceof PsiCapturedWildcardType && wildcardType.isExtends() != ((PsiCapturedWildcardType)newBound).getWildcard().isExtends()) {
|
||||
return handleBoundComposition(wildcardType, ((PsiCapturedWildcardType)newBound).getWildcard());
|
||||
if (newBound instanceof PsiCapturedWildcardType) {
|
||||
final PsiWildcardType wildcard = ((PsiCapturedWildcardType)newBound).getWildcard();
|
||||
if (wildcardType.isExtends() != wildcard.isExtends()) {
|
||||
return wildcard.isBounded() ? PsiWildcardType.createUnbounded(wildcardType.getManager()) : newBound;
|
||||
}
|
||||
}
|
||||
|
||||
return PsiWildcardType.changeBound(wildcardType, newBound);
|
||||
|
||||
@@ -6,4 +6,12 @@ class A {
|
||||
System.out.println(t.<error descr="'value' has private access in 'A'">value</error>);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Foo<T extends Foo<T>> {
|
||||
private int field;
|
||||
|
||||
public int bar(T t){
|
||||
return t.<error descr="'field' has private access in 'Foo'">field</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import java.util.*;
|
||||
class GenericsTest<T> {
|
||||
|
||||
static <S> S next(GenericsTest<S> test)
|
||||
{
|
||||
System.out.println(test);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
return new Iterator<T>() {
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next()
|
||||
{
|
||||
return GenericsTest.next(GenericsTest.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class GenericsTest1<T> {
|
||||
|
||||
static <S> S next1(GenericsTest1<S> test)
|
||||
{
|
||||
System.out.println(test);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
return new Iterator<T>() {
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next()
|
||||
{
|
||||
return GenericsTest1.next1(GenericsTest1.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GenericsTest2<T> {
|
||||
|
||||
static <S> S next2(GenericsTest2<S> test)
|
||||
{
|
||||
System.out.println(test);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
return new Iterator<T>() {
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next()
|
||||
{
|
||||
return next2(GenericsTest2.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -244,3 +238,12 @@ class Use99<U extends GenericTest99<?,F>,F> {
|
||||
class Use99n extends Use99<GenericTest99D<?>,Double> {
|
||||
}
|
||||
//end of IDEADEV-8697
|
||||
|
||||
class IDEA79360 {
|
||||
public static void main(Map<?, ?> map, Map<Object, Object> test) {
|
||||
map.putAll<error descr="'putAll(java.util.Map<capture<?>,capture<?>>)' in 'java.util.Map' cannot be applied to '(java.util.Map<java.lang.Object,java.lang.Object>)'">(test)</error>;
|
||||
map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>;
|
||||
map.put<error descr="'put(capture<?>, capture<?>)' in 'java.util.Map' cannot be applied to '(java.lang.Object, java.lang.Object)'">(new Object(), new Object())</error>;
|
||||
map = new HashMap<Object, Object>(test);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems/>
|
||||
@@ -0,0 +1,7 @@
|
||||
public abstract class Foo<T extends Foo<T>> {
|
||||
private int field;
|
||||
|
||||
public int bar(T t){
|
||||
return ((Foo<T>)t).field;
|
||||
}
|
||||
}
|
||||
@@ -1252,4 +1252,15 @@ class Foo {
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
public void testVarargParenthesis() {
|
||||
myFixture.configureByText 'a.java', '''
|
||||
class Foo {
|
||||
void foo(File... files) { }
|
||||
{ foo(new <caret>) }
|
||||
}
|
||||
'''
|
||||
type 'File('
|
||||
assert myFixture.file.text.contains('new File()')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,6 +119,8 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testTypeParameterBoundVisibility() throws Exception { doTest(false);}
|
||||
public void testTypeParameterBoundVisibilityJdk14() throws Exception { doTest(false);}
|
||||
|
||||
public void testUncheckedWarningsLevel6() throws Exception { doTest(true);}
|
||||
|
||||
public void testJavaUtilCollections_NoVerify() throws Exception {
|
||||
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -37,6 +37,8 @@ public class RedundantCast15Test extends InspectionTestCase {
|
||||
|
||||
public void testRawCastsToAvoidIncompatibility() throws Exception { doTest();}
|
||||
|
||||
public void testTypeParameterAccessChecksJava7() throws Exception { doTest();}
|
||||
|
||||
public void testIgnore() throws Exception {
|
||||
final RedundantCastInspection castInspection = new RedundantCastInspection();
|
||||
castInspection.IGNORE_ANNOTATED_METHODS = true;
|
||||
|
||||
@@ -436,7 +436,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{
|
||||
PsiType type1 = aClass.getFields()[1].getType();
|
||||
PsiElement target1 = PsiUtil.resolveClassInType(type1);
|
||||
assertNotNull(target1);
|
||||
PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", RESOLVE_SCOPE);
|
||||
PsiClass objectClass = myJavaFacade.findClasses("java.lang.Object", RESOLVE_SCOPE)[1];
|
||||
assertEquals(objectClass, target1);
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ public class ClsRepositoryUseTest extends PsiTestCase{
|
||||
assertFalse(type2 instanceof PsiPrimitiveType);
|
||||
PsiClass target2 = PsiUtil.resolveClassInType(type2);
|
||||
assertNotNull(target2);
|
||||
PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", RESOLVE_SCOPE);
|
||||
PsiClass objectClass = myJavaFacade.findClasses("java.lang.Object", RESOLVE_SCOPE)[1];
|
||||
assertEquals(objectClass, target2);
|
||||
|
||||
parameters[0].getModifierList();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -37,7 +37,7 @@ public class CreateDirectoryOrPackageAction extends AnAction implements DumbAwar
|
||||
IdeView view = e.getData(LangDataKeys.IDE_VIEW);
|
||||
Project project = e.getData(PlatformDataKeys.PROJECT);
|
||||
|
||||
if (view == null) {
|
||||
if (view == null || project == null) {
|
||||
return;
|
||||
}
|
||||
PsiDirectory directory = DirectoryChooserUtil.getOrChooseDirectory(view);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.intellij.util.ui.DialogUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -224,7 +225,7 @@ public abstract class DialogWrapper {
|
||||
* @param canBeParent can be parent
|
||||
* @throws IllegalStateException if the dialog is invoked not on the event dispatch thread
|
||||
*/
|
||||
protected DialogWrapper(Component parent, boolean canBeParent) {
|
||||
protected DialogWrapper(@NotNull Component parent, boolean canBeParent) {
|
||||
ensureEventDispatchThread();
|
||||
myPeer = createPeer(parent, canBeParent);
|
||||
createDefaultActions();
|
||||
|
||||
@@ -101,14 +101,14 @@ public class Messages {
|
||||
/**
|
||||
* Please, use {@link #showOkCancelDialog} or {@link #showYesNoCancelDialog} if possible (these dialogs implements native OS behavior)!
|
||||
*/
|
||||
public static int showDialog(Project project, String message, String title, String[] options, int defaultOptionIndex, @Nullable Icon icon) {
|
||||
public static int showDialog(@Nullable Project project, String message, String title, String[] options, int defaultOptionIndex, @Nullable Icon icon) {
|
||||
return showDialog(project, message, title, options, defaultOptionIndex, icon, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Please, use {@link #showOkCancelDialog} or {@link #showYesNoCancelDialog} if possible (these dialogs implements native OS behavior)!
|
||||
*/
|
||||
public static int showDialog(Project project, String message, String title, String[] options, int defaultOptionIndex, @Nullable Icon icon,
|
||||
public static int showDialog(@Nullable Project project, String message, String title, String[] options, int defaultOptionIndex, @Nullable Icon icon,
|
||||
@Nullable DialogWrapper.DoNotAskOption doNotAskOption) {
|
||||
if (isApplicationInUnitTestOrHeadless()) {
|
||||
return ourTestImplementation.show(message);
|
||||
@@ -238,7 +238,7 @@ public class Messages {
|
||||
/**
|
||||
* @return <code>0</code> if user pressed "Yes" and returns <code>1</code> if user pressed "No" button.
|
||||
*/
|
||||
public static int showYesNoDialog(Project project, String message, String title, String yesText, String noText, @Nullable Icon icon) {
|
||||
public static int showYesNoDialog(@Nullable Project project, String message, String title, String yesText, String noText, @Nullable Icon icon) {
|
||||
if (canShowMacSheetPanel()) {
|
||||
return MacMessages.getInstance().showYesNoDialog(title, message, yesText, noText, WindowManager.getInstance().suggestParentWindow(project));
|
||||
}
|
||||
@@ -249,7 +249,7 @@ public class Messages {
|
||||
/**
|
||||
* @return <code>0</code> if user pressed "Yes" and returns <code>1</code> if user pressed "No" button.
|
||||
*/
|
||||
public static int showYesNoDialog(Project project, String message, String title, @Nullable Icon icon) {
|
||||
public static int showYesNoDialog(@Nullable Project project, String message, String title, @Nullable Icon icon) {
|
||||
if (canShowMacSheetPanel()) {
|
||||
return MacMessages.getInstance().showYesNoDialog(title, message, YES_BUTTON, NO_BUTTON, WindowManager.getInstance().suggestParentWindow(project));
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class WindowManager {
|
||||
* that can be parent.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Window suggestParentWindow(Project project);
|
||||
public abstract Window suggestParentWindow(@Nullable Project project);
|
||||
|
||||
/**
|
||||
* Get the status bar for the project's main frame
|
||||
|
||||
@@ -35,7 +35,7 @@ public class UiNotifyConnector implements Disposable, HierarchyListener{
|
||||
private final WeakReference<Component> myComponent;
|
||||
private Activatable myTarget;
|
||||
|
||||
public UiNotifyConnector(final Component component, final Activatable target) {
|
||||
public UiNotifyConnector(@NotNull final Component component, @NotNull final Activatable target) {
|
||||
myComponent = new WeakReference<Component>(component);
|
||||
myTarget = target;
|
||||
if (component.isShowing()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,8 +245,8 @@ public class ActionInstallPlugin extends AnAction implements DumbAware {
|
||||
for (PluginNode pluginNode : list) {
|
||||
final String idString = pluginNode.getPluginId().getIdString();
|
||||
final PluginManagerUISettings pluginManagerUISettings = PluginManagerUISettings.getInstance();
|
||||
if (!pluginManagerUISettings.myInstalledPlugins.contains(idString)) {
|
||||
pluginManagerUISettings.myInstalledPlugins.add(idString);
|
||||
if (!pluginManagerUISettings.getInstalledPlugins().contains(idString)) {
|
||||
pluginManagerUISettings.getInstalledPlugins().add(idString);
|
||||
}
|
||||
pluginManagerUISettings.myOutdatedPlugins.remove(idString);
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -106,7 +106,7 @@ public class ActionUninstallPlugin extends AnAction implements DumbAware {
|
||||
|
||||
try {
|
||||
PluginInstaller.prepareToUninstall(pluginId);
|
||||
final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().myInstalledPlugins;
|
||||
final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().getInstalledPlugins();
|
||||
final String pluginIdString = pluginId.getIdString();
|
||||
while (installedPlugins.contains(pluginIdString)) {
|
||||
installedPlugins.remove(pluginIdString);
|
||||
|
||||
@@ -255,7 +255,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
int state = StringUtil.compareVersionNumbers(descr.getVersion(), existing.getVersion());
|
||||
final PluginId pluginId = existing.getPluginId();
|
||||
final String idString = pluginId.getIdString();
|
||||
final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().myInstalledPlugins;
|
||||
final JDOMExternalizableStringList installedPlugins = PluginManagerUISettings.getInstance().getInstalledPlugins();
|
||||
if (!installedPlugins.contains(idString) && !((IdeaPluginDescriptorImpl)existing).isDeleted()){
|
||||
installedPlugins.add(idString);
|
||||
}
|
||||
@@ -537,7 +537,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
|
||||
}
|
||||
myBundledLabel.setText("From " + presentableUrl);
|
||||
} else {
|
||||
if (PluginManagerUISettings.getInstance().myInstalledPlugins.contains(idString)) {
|
||||
if (PluginManagerUISettings.getInstance().getInstalledPlugins().contains(idString)) {
|
||||
myBundledLabel.setText("From repository");
|
||||
} else {
|
||||
myBundledLabel.setText("Custom");
|
||||
|
||||
@@ -120,7 +120,7 @@ class PluginManagerColumnInfo extends ColumnInfo<IdeaPluginDescriptor, String> {
|
||||
if (PluginManager.isPluginInstalled(pluginId)) {
|
||||
return false;
|
||||
}
|
||||
return PluginManagerUISettings.getInstance().myInstalledPlugins.contains(pluginId.getIdString());
|
||||
return PluginManagerUISettings.getInstance().getInstalledPlugins().contains(pluginId.getIdString());
|
||||
}
|
||||
|
||||
public Comparator<IdeaPluginDescriptor> getComparator() {
|
||||
|
||||
@@ -50,13 +50,18 @@ public class PluginManagerUISettings implements PersistentStateComponent<Element
|
||||
public boolean AVAILABLE_SORT_BY_STATUS = false;
|
||||
public boolean INSTALLED_SORT_BY_STATUS = false;
|
||||
public JDOMExternalizableStringList myOutdatedPlugins = new JDOMExternalizableStringList();
|
||||
public JDOMExternalizableStringList myInstalledPlugins = new JDOMExternalizableStringList();
|
||||
|
||||
private JDOMExternalizableStringList myInstalledPlugins = new JDOMExternalizableStringList();
|
||||
|
||||
@NonNls private static final String AVAILABLE_PROPORTIONS = "available-proportions";
|
||||
|
||||
private final SplitterProportionsData mySplitterProportionsData = new SplitterProportionsDataImpl();
|
||||
private final SplitterProportionsData myAvailableSplitterProportionsData = new SplitterProportionsDataImpl();
|
||||
|
||||
public JDOMExternalizableStringList getInstalledPlugins() {
|
||||
return myInstalledPlugins;
|
||||
}
|
||||
|
||||
public static PluginManagerUISettings getInstance() {
|
||||
return ServiceManager.getService(PluginManagerUISettings.class);
|
||||
}
|
||||
|
||||
@@ -5099,6 +5099,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
for (EditorMouseListener mouseListener : myMouseListeners) {
|
||||
mouseListener.mousePressed(event);
|
||||
}
|
||||
putUserData(EditorActionUtil.EXPECTED_CARET_OFFSET, null);
|
||||
|
||||
// On some systems (for example on Linux) popup trigger is MOUSE_PRESSED event.
|
||||
// But this trigger is always consumed by popup handler. In that case we have to
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -57,7 +57,7 @@ public final class TestWindowManager extends WindowManagerEx implements Applicat
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Window suggestParentWindow(final Project project) {
|
||||
public final Window suggestParentWindow(@Nullable final Project project) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.designSurface;
|
||||
|
||||
import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public abstract class AbstractEditOperation extends com.intellij.designer.designSurface.AbstractEditOperation {
|
||||
protected final RadViewComponent myContainer;
|
||||
|
||||
public AbstractEditOperation(RadViewComponent container, OperationContext context) {
|
||||
super(context);
|
||||
myContainer = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
if (myContext.isAdd() || myContext.isMove()) {
|
||||
for (RadComponent component : myComponents) {
|
||||
ModelParser.moveComponent(myContainer, (RadViewComponent)component, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (RadComponent component : myComponents) {
|
||||
ModelParser.addComponent(myContainer, (RadViewComponent)component, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import com.intellij.android.designer.actions.ProfileAction;
|
||||
import com.intellij.android.designer.componentTree.AndroidTreeDecorator;
|
||||
import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.PropertyParser;
|
||||
import com.intellij.android.designer.model.RadViewAnimatorLayout;
|
||||
import com.intellij.android.designer.model.viewAnimator.RadViewAnimatorLayout;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.profile.ProfileManager;
|
||||
import com.intellij.designer.DesignerToolWindowManager;
|
||||
|
||||
@@ -15,41 +15,22 @@
|
||||
*/
|
||||
package com.intellij.android.designer.designSurface;
|
||||
|
||||
import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.FeedbackLayer;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.designSurface.feedbacks.AlphaComponent;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class DropToOperation implements EditOperation {
|
||||
private final RadViewComponent myContainer;
|
||||
private final OperationContext myContext;
|
||||
private List<RadComponent> myComponents;
|
||||
public class DropToOperation extends AbstractEditOperation {
|
||||
private JComponent myFeedback;
|
||||
|
||||
public DropToOperation(RadViewComponent container, OperationContext context) {
|
||||
myContainer = container;
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponent(RadComponent component) {
|
||||
myComponents = Collections.singletonList(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComponents(List<RadComponent> components) {
|
||||
myComponents = components;
|
||||
super(container, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,23 +54,4 @@ public class DropToOperation implements EditOperation {
|
||||
myFeedback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
if (myContext.isAdd() || myContext.isMove()) {
|
||||
for (RadComponent component : myComponents) {
|
||||
ModelParser.moveComponent(myContainer, (RadViewComponent)component, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (RadComponent component : myComponents) {
|
||||
ModelParser.addComponent(myContainer, (RadViewComponent)component, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* 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.designSurface.layout;
|
||||
|
||||
import com.intellij.android.designer.designSurface.AbstractEditOperation;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.designer.designSurface.FeedbackLayer;
|
||||
import com.intellij.designer.designSurface.OperationContext;
|
||||
import com.intellij.designer.designSurface.feedbacks.AlphaComponent;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.LightColors;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public class FrameLayoutOperation extends AbstractEditOperation {
|
||||
private GravityFeedback myFeedback;
|
||||
private JLabel myTextFeedback;
|
||||
private String myGravity;
|
||||
private Set<Pair<Gravity, Gravity>> myExcludes;
|
||||
|
||||
public FrameLayoutOperation(RadViewComponent container, OperationContext context) {
|
||||
super(container, context);
|
||||
|
||||
if (context.isMove()) {
|
||||
myExcludes = new HashSet<Pair<Gravity, Gravity>>();
|
||||
|
||||
for (RadComponent component : context.getComponents()) {
|
||||
String value = ((RadViewComponent)component).getTag().getAttributeValue("android:layout_gravity");
|
||||
if (StringUtil.isEmpty(value)) {
|
||||
myExcludes.add(new Pair<Gravity, Gravity>(Gravity.Left, Gravity.Top));
|
||||
}
|
||||
else {
|
||||
for (String option : StringUtil.split(value, "|")) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createFeedback(FeedbackLayer layer, Rectangle bounds) {
|
||||
if (myFeedback == null) {
|
||||
myFeedback = new GravityFeedback();
|
||||
layer.add(myFeedback);
|
||||
myFeedback.setBounds(bounds);
|
||||
|
||||
myTextFeedback = new JLabel();
|
||||
myTextFeedback.setFont(myTextFeedback.getFont().deriveFont(Font.BOLD));
|
||||
myTextFeedback.setBackground(LightColors.YELLOW);
|
||||
myTextFeedback.setBorder(IdeBorderFactory.createEmptyBorder(0, 3, 2, 0));
|
||||
myTextFeedback.setOpaque(true);
|
||||
layer.add(myTextFeedback);
|
||||
|
||||
layer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedback() {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
Rectangle bounds = myContainer.getBounds(layer);
|
||||
|
||||
createFeedback(layer, bounds);
|
||||
|
||||
Point location = myContext.getLocation();
|
||||
Gravity horizontal = calculateHorizontal(bounds, location);
|
||||
Gravity vertical = calculateVertical(bounds, location);
|
||||
|
||||
if (myContext.isMove() && myExcludes.contains(new Pair<Gravity, Gravity>(horizontal, vertical))) {
|
||||
horizontal = vertical = null;
|
||||
}
|
||||
|
||||
myFeedback.setGravity(horizontal, vertical);
|
||||
configureTextFeedback(bounds, horizontal, vertical);
|
||||
|
||||
configureGravity(horizontal, vertical);
|
||||
}
|
||||
|
||||
private void configureTextFeedback(Rectangle bounds, Gravity horizontal, Gravity vertical) {
|
||||
if (horizontal == null || vertical == null) {
|
||||
myTextFeedback.setText("None");
|
||||
}
|
||||
else {
|
||||
myTextFeedback.setText("[" + vertical.name() + ", " + horizontal.name() + "]");
|
||||
}
|
||||
|
||||
Dimension textSize = myTextFeedback.getPreferredSize();
|
||||
myTextFeedback
|
||||
.setBounds(bounds.x + bounds.width / 2 - textSize.width / 2, bounds.y - textSize.height - 10, textSize.width, textSize.height);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Gravity calculateHorizontal(Rectangle bounds, Point location) {
|
||||
Gravity horizontal = null;
|
||||
double left = bounds.x + bounds.width / 3.0;
|
||||
double right = bounds.x + 2 * bounds.width / 3.0;
|
||||
|
||||
if (location.x < left) {
|
||||
horizontal = Gravity.Left;
|
||||
}
|
||||
else if (left < location.x && location.x < right) {
|
||||
horizontal = Gravity.Center;
|
||||
}
|
||||
else if (location.x > right) {
|
||||
horizontal = Gravity.Right;
|
||||
}
|
||||
|
||||
return horizontal;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Gravity calculateVertical(Rectangle bounds, Point location) {
|
||||
Gravity vertical = null;
|
||||
double top = bounds.y + bounds.height / 3.0;
|
||||
double bottom = bounds.y + 2 * bounds.height / 3.0;
|
||||
|
||||
if (location.y < top) {
|
||||
vertical = Gravity.Top;
|
||||
}
|
||||
else if (top < location.y && location.y < bottom) {
|
||||
vertical = Gravity.Center;
|
||||
}
|
||||
else if (location.y > bottom) {
|
||||
vertical = Gravity.Bottom;
|
||||
}
|
||||
|
||||
return vertical;
|
||||
}
|
||||
|
||||
private void configureGravity(Gravity horizontal, Gravity vertical) {
|
||||
StringBuffer gravity = new StringBuffer();
|
||||
|
||||
if (horizontal == Gravity.Center && vertical == Gravity.Center) {
|
||||
gravity.append("center");
|
||||
}
|
||||
else {
|
||||
if (horizontal == Gravity.Left) {
|
||||
gravity.append("left");
|
||||
}
|
||||
else if (horizontal == Gravity.Center) {
|
||||
gravity.append("center_horizontal");
|
||||
}
|
||||
else if (horizontal == Gravity.Right) {
|
||||
gravity.append("right");
|
||||
}
|
||||
|
||||
if (vertical == Gravity.Top) {
|
||||
if (gravity.length() > 0) {
|
||||
gravity.append("|");
|
||||
}
|
||||
gravity.append("top");
|
||||
}
|
||||
else if (vertical == Gravity.Center) {
|
||||
if (gravity.length() > 0) {
|
||||
gravity.append("|");
|
||||
}
|
||||
gravity.append("center_vertical");
|
||||
}
|
||||
else if (vertical == Gravity.Bottom) {
|
||||
if (gravity.length() > 0) {
|
||||
gravity.append("|");
|
||||
}
|
||||
gravity.append("bottom");
|
||||
}
|
||||
}
|
||||
|
||||
myGravity = gravity.length() == 0 ? null : gravity.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eraseFeedback() {
|
||||
if (myFeedback != null) {
|
||||
FeedbackLayer layer = myContext.getArea().getFeedbackLayer();
|
||||
layer.remove(myFeedback);
|
||||
layer.remove(myTextFeedback);
|
||||
layer.repaint();
|
||||
myFeedback = null;
|
||||
myTextFeedback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute() {
|
||||
return myGravity != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
super.execute();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (RadComponent component : myComponents) {
|
||||
((RadViewComponent)component).getTag().setAttribute("android:layout_gravity", myGravity);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Feedback
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class GravityFeedback extends AlphaComponent {
|
||||
private static final Gravity[] HORIZONTAL = {Gravity.Left, Gravity.Center, Gravity.Right};
|
||||
private static final Gravity[] VERTICAL = {Gravity.Top, Gravity.Center, Gravity.Bottom};
|
||||
|
||||
private static final int SPACE = 5;
|
||||
|
||||
private Gravity myHorizontal;
|
||||
private Gravity myVertical;
|
||||
|
||||
public GravityFeedback() {
|
||||
super(Color.green);
|
||||
}
|
||||
|
||||
public void setGravity(Gravity horizontal, Gravity vertical) {
|
||||
myHorizontal = horizontal;
|
||||
myVertical = vertical;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintOther1(Graphics2D g2d) {
|
||||
for (Gravity h : HORIZONTAL) {
|
||||
for (Gravity v : VERTICAL) {
|
||||
paintCell(g2d, h, v, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintOther2(Graphics2D g2d) {
|
||||
for (Gravity h : HORIZONTAL) {
|
||||
for (Gravity v : VERTICAL) {
|
||||
if (paintCell(g2d, h, v, true)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean paintCell(Graphics2D g2d, Gravity horizontal, Gravity vertical, boolean selection) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = getWidth() / 3;
|
||||
int height = getHeight() / 3;
|
||||
|
||||
if (horizontal == Gravity.Center) {
|
||||
x = width;
|
||||
}
|
||||
else if (horizontal == Gravity.Right) {
|
||||
x = getWidth() - width;
|
||||
}
|
||||
|
||||
if (vertical == Gravity.Center) {
|
||||
y = height;
|
||||
}
|
||||
else if (vertical == Gravity.Bottom) {
|
||||
y = getHeight() - height;
|
||||
}
|
||||
|
||||
if (selection) {
|
||||
if (myHorizontal == horizontal && myVertical == vertical) {
|
||||
Color oldColor = g2d.getColor();
|
||||
g2d.setColor(LightColors.YELLOW);
|
||||
g2d.fillRect(x + SPACE, y + SPACE, width - 2 * SPACE, height - 2 * SPACE);
|
||||
g2d.setColor(oldColor);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
g2d.fillRect(x + SPACE, y + SPACE, width - 2 * SPACE, height - 2 * SPACE);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -13,13 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports;
|
||||
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
package com.intellij.android.designer.designSurface.layout;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public interface GrImportReference extends GroovyPsiElement {
|
||||
}
|
||||
public enum Gravity {
|
||||
Left, Right, Center, Top, Bottom
|
||||
}
|
||||
|
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,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
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -13,17 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports;
|
||||
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.UserDataHolderEx;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
package com.intellij.android.designer.model;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
* @author Alexander Lobas
|
||||
*/
|
||||
public interface GrImportSelector extends GroovyPsiElement {
|
||||
}
|
||||
public abstract class RadViewLayoutWithData extends RadViewLayout {
|
||||
public abstract String[] getLayoutParams();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.layout;
|
||||
|
||||
import com.intellij.android.designer.designSurface.TreeDropToOperation;
|
||||
import com.intellij.android.designer.designSurface.layout.FrameLayoutOperation;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.model.RadViewLayoutWithData;
|
||||
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 EditOperation processChildOperation(OperationContext context) {
|
||||
if (context.isCreate() || context.isPaste() || context.isAdd() || context.isMove()) {
|
||||
if (context.isTree()) {
|
||||
return new TreeDropToOperation(myContainer, context);
|
||||
}
|
||||
return new FrameLayoutOperation((RadViewComponent)myContainer, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentDecorator getChildSelectionDecorator(RadComponent component, List<RadComponent> selection) {
|
||||
return super.getChildSelectionDecorator(component, selection); // 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
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
package com.intellij.android.designer.model.layout;
|
||||
|
||||
import com.intellij.android.designer.model.ModelParser;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.model.RadViewLayoutWithData;
|
||||
import com.intellij.designer.componentTree.TreeEditOperation;
|
||||
import com.intellij.designer.designSurface.EditOperation;
|
||||
import com.intellij.designer.designSurface.FeedbackLayer;
|
||||
@@ -30,7 +33,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()) {
|
||||
@@ -13,8 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
package com.intellij.android.designer.model.scroll;
|
||||
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.android.designer.model.ViewsMetaManager;
|
||||
import com.intellij.designer.designSurface.DesignerEditorPanel;
|
||||
import com.intellij.designer.model.MetaManager;
|
||||
import com.intellij.designer.model.MetaModel;
|
||||
@@ -13,8 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
package com.intellij.android.designer.model.scroll;
|
||||
|
||||
import com.intellij.android.designer.model.RadSingleChildrenViewLayout;
|
||||
import com.intellij.android.designer.model.RadViewComponent;
|
||||
import com.intellij.designer.designSurface.DesignerEditorPanel;
|
||||
import com.intellij.designer.model.RadComponent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.android.designer.model;
|
||||
package com.intellij.android.designer.model.viewAnimator;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||
@@ -13,9 +13,7 @@
|
||||
* 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.OperationContext;
|
||||
package com.intellij.android.designer.model.viewAnimator;
|
||||
|
||||
/**
|
||||
* @author Alexander Lobas
|
||||