Merge remote-tracking branch 'origin/master'
@@ -30,6 +30,8 @@ public class RegExpBraceMatcher implements PairedBraceMatcher {
|
||||
new BracePair(RegExpTT.POS_LOOKBEHIND, RegExpTT.GROUP_END, true), new BracePair(RegExpTT.NEG_LOOKBEHIND, RegExpTT.GROUP_END, true),
|
||||
new BracePair(RegExpTT.PYTHON_NAMED_GROUP, RegExpTT.GROUP_END, true),
|
||||
new BracePair(RegExpTT.PYTHON_NAMED_GROUP_REF, RegExpTT.GROUP_END, true),
|
||||
new BracePair(RegExpTT.RUBY_NAMED_GROUP, RegExpTT.GROUP_END, true),
|
||||
new BracePair(RegExpTT.RUBY_QUOTED_NAMED_GROUP, RegExpTT.GROUP_END, true),
|
||||
new BracePair(RegExpTT.CLASS_BEGIN, RegExpTT.CLASS_END, false), new BracePair(RegExpTT.LBRACE, RegExpTT.RBRACE, false),
|
||||
new BracePair(RegExpTT.QUOTE_BEGIN, RegExpTT.QUOTE_END, false),};
|
||||
}
|
||||
|
||||
@@ -120,6 +120,16 @@ public class RegExpHighlighter extends SyntaxHighlighterBase {
|
||||
keys1.put(RegExpTT.QUOTE_BEGIN, QUOTE_CHARACTER);
|
||||
keys1.put(RegExpTT.QUOTE_END, QUOTE_CHARACTER);
|
||||
|
||||
keys1.put(RegExpTT.NON_CAPT_GROUP, PARENTHS);
|
||||
keys1.put(RegExpTT.POS_LOOKBEHIND, PARENTHS);
|
||||
keys1.put(RegExpTT.NEG_LOOKBEHIND, PARENTHS);
|
||||
keys1.put(RegExpTT.POS_LOOKAHEAD, PARENTHS);
|
||||
keys1.put(RegExpTT.NEG_LOOKAHEAD, PARENTHS);
|
||||
keys1.put(RegExpTT.SET_OPTIONS, PARENTHS);
|
||||
keys1.put(RegExpTT.PYTHON_NAMED_GROUP, PARENTHS);
|
||||
keys1.put(RegExpTT.PYTHON_NAMED_GROUP_REF, PARENTHS);
|
||||
keys1.put(RegExpTT.RUBY_NAMED_GROUP, PARENTHS);
|
||||
keys1.put(RegExpTT.RUBY_QUOTED_NAMED_GROUP, PARENTHS);
|
||||
keys1.put(RegExpTT.GROUP_BEGIN, PARENTHS);
|
||||
keys1.put(RegExpTT.GROUP_END, PARENTHS);
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ public interface RegExpGroup extends RegExpAtom {
|
||||
|
||||
boolean isRubyNamedGroup();
|
||||
|
||||
boolean isNamedGroup();
|
||||
|
||||
@Nullable
|
||||
String getGroupName();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ public class RegExpGroupImpl extends RegExpElementImpl implements RegExpGroup {
|
||||
getNode().findChildByType(RegExpTT.RUBY_QUOTED_NAMED_GROUP) != null;
|
||||
}
|
||||
|
||||
public boolean isNamedGroup() {
|
||||
return getNode().findChildByType(RegExpTT.RUBY_NAMED_GROUP) != null;
|
||||
}
|
||||
|
||||
public String getGroupName() {
|
||||
if (!isPythonNamedGroup()) {
|
||||
return null;
|
||||
|
||||
@@ -124,14 +124,14 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
|
||||
public void visitRegExpBackref(final RegExpBackref backref) {
|
||||
final RegExpGroup group = backref.resolve();
|
||||
if (group == null) {
|
||||
final Annotation a = myHolder.createErrorAnnotation(backref, "Unresolved backreference");
|
||||
final Annotation a = myHolder.createErrorAnnotation(backref, "Unresolved back reference");
|
||||
if (a != null) {
|
||||
// IDEA-9381
|
||||
a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
}
|
||||
}
|
||||
else if (PsiTreeUtil.isAncestor(group, backref, true)) {
|
||||
myHolder.createWarningAnnotation(backref, "Backreference is nested into the capturing group it refers to");
|
||||
myHolder.createWarningAnnotation(backref, "Back reference is nested into the capturing group it refers to");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
|
||||
*/
|
||||
final RegExpGroup group = groupRef.resolve();
|
||||
if (group == null) {
|
||||
final Annotation a = myHolder.createErrorAnnotation(groupRef, "Unresolved backreference");
|
||||
final Annotation a = myHolder.createErrorAnnotation(groupRef, "Unresolved back reference");
|
||||
if (a != null) {
|
||||
// IDEA-9381
|
||||
a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
|
||||
@@ -719,7 +719,7 @@
|
||||
<expected>ERR</expected>
|
||||
</test>
|
||||
<test verify="false">
|
||||
<pattern><![CDATA[([ab]+=<warning descr="Backreference is nested into the capturing group it refers to">\1</warning>)]]></pattern>
|
||||
<pattern><![CDATA[([ab]+=<warning descr="Back reference is nested into the capturing group it refers to">\1</warning>)]]></pattern>
|
||||
<expected>OK</expected>
|
||||
</test>
|
||||
</backrefs>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<jvmarg line=""-Dmodules.output=${modules.output}""/>
|
||||
<jvmarg line=""-Dgant.script=@{script}""/>
|
||||
<jvmarg line=""-Dgant.target=@{target}""/>
|
||||
<jvmarg line="-DmaySkipAndroidPlugin=true"/>
|
||||
|
||||
<classpath>
|
||||
<fileset dir="${project.home}/lib/ant/lib">
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
@@ -80,8 +81,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
//noinspection unchecked
|
||||
final List<SmartStepTarget> targets = new OrderedSet<SmartStepTarget>();
|
||||
|
||||
TextRange textRange = element.getTextRange();
|
||||
final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(textRange.getStartOffset()), doc.getLineNumber(textRange.getEndOffset()));
|
||||
final Ref<TextRange> textRange = new Ref<TextRange>(lineRange);
|
||||
|
||||
final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() {
|
||||
final Stack<PsiMethod> myContextStack = new Stack<PsiMethod>();
|
||||
@@ -96,12 +96,12 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
@Override
|
||||
public void visitAnonymousClass(PsiAnonymousClass aClass) {
|
||||
for (PsiMethod psiMethod : aClass.getMethods()) {
|
||||
targets.add(new MethodSmartStepTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true, lines));
|
||||
targets.add(new MethodSmartStepTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void visitLambdaExpression(PsiLambdaExpression expression) {
|
||||
targets.add(new LambdaSmartStepTarget(expression, getCurrentParamName(), expression.getBody(), myNextLambdaExpressionOrdinal++, lines));
|
||||
targets.add(new LambdaSmartStepTarget(expression, getCurrentParamName(), expression.getBody(), myNextLambdaExpressionOrdinal++, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,6 +111,15 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExpression(PsiExpression expression) {
|
||||
TextRange range = expression.getTextRange();
|
||||
if (lineRange.intersects(range)) {
|
||||
textRange.set(textRange.get().union(range));
|
||||
}
|
||||
super.visitExpression(expression);
|
||||
}
|
||||
|
||||
public void visitExpressionList(PsiExpressionList expressionList) {
|
||||
final PsiMethod psiMethod = myContextStack.isEmpty()? null : myContextStack.peek();
|
||||
if (psiMethod != null) {
|
||||
@@ -146,7 +155,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
((PsiMethodCallExpression)expression).getMethodExpression().getReferenceNameElement()
|
||||
: expression instanceof PsiNewExpression? ((PsiNewExpression)expression).getClassOrAnonymousClassReference() : expression,
|
||||
false,
|
||||
lines
|
||||
null
|
||||
));
|
||||
}
|
||||
try {
|
||||
@@ -168,6 +177,11 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
|
||||
}
|
||||
sibling.accept(methodCollector);
|
||||
}
|
||||
|
||||
Range<Integer> lines = new Range<Integer>(doc.getLineNumber(textRange.get().getStartOffset()), doc.getLineNumber(textRange.get().getEndOffset()));
|
||||
for (SmartStepTarget target : targets) {
|
||||
target.setCallingExpressionLines(lines);
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -27,7 +27,7 @@ public abstract class SmartStepTarget {
|
||||
private final PsiElement myHighlightElement;
|
||||
private final String myLabel;
|
||||
private final boolean myNeedBreakpointRequest;
|
||||
private final Range<Integer> myExpressionLines;
|
||||
private Range<Integer> myExpressionLines;
|
||||
|
||||
protected SmartStepTarget(@Nullable String label, @Nullable PsiElement highlightElement, boolean needBreakpointRequest, Range<Integer> expressionLines) {
|
||||
myHighlightElement = highlightElement;
|
||||
@@ -53,4 +53,8 @@ public abstract class SmartStepTarget {
|
||||
public Range<Integer> getCallingExpressionLines() {
|
||||
return myExpressionLines;
|
||||
}
|
||||
|
||||
public void setCallingExpressionLines(Range<Integer> expressionLines) {
|
||||
myExpressionLines = expressionLines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.intellij.xdebugger.frame.XStackFrame;
|
||||
import com.sun.jdi.InternalException;
|
||||
@@ -101,9 +102,29 @@ public class CompoundPositionManager extends PositionManagerEx {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static int mapToOriginalLine(int line, int[] mapping) {
|
||||
for (int i = 0; i < mapping.length; i += 2) {
|
||||
if (mapping[i + 1] == line) {
|
||||
return mapping[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<Location> locationsOfLine(@NotNull ReferenceType type, @NotNull SourcePosition position) {
|
||||
VirtualFile file = position.getFile().getVirtualFile();
|
||||
if (file != null) {
|
||||
int[] data = file.getUserData(LINE_NUMBERS_MAPPING_KEY);
|
||||
if (data != null) {
|
||||
int line = mapToOriginalLine(position.getLine() + 1, data);
|
||||
if (line > -1) {
|
||||
position = SourcePosition.createFromLine(position.getFile(), line - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionManager positionManager : myPositionManagers) {
|
||||
try {
|
||||
return positionManager.locationsOfLine(type, position);
|
||||
|
||||
@@ -140,7 +140,7 @@ public class PositionManagerImpl implements PositionManager {
|
||||
lineNumber = -1;
|
||||
}
|
||||
|
||||
if (psiFile instanceof PsiCompiledElement && lineNumber > -1) {
|
||||
if (lineNumber > -1) {
|
||||
VirtualFile file = psiFile.getVirtualFile();
|
||||
if (file != null) {
|
||||
int[] data = file.getUserData(LINE_NUMBERS_MAPPING_KEY);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.debugger.ui.breakpoints;
|
||||
|
||||
import com.intellij.debugger.PositionManager;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
@@ -81,8 +82,8 @@ public abstract class JavaLineBreakpointTypeBase<P extends JavaBreakpointPropert
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canPutAt(@NotNull VirtualFile file, final int line, @NotNull Project project) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
public final boolean canPutAt(@NotNull final VirtualFile file, final int line, @NotNull Project project) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
// JSPX supports jvm debugging, but not in XHTML files
|
||||
if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML) {
|
||||
return false;
|
||||
@@ -128,6 +129,9 @@ public abstract class JavaLineBreakpointTypeBase<P extends JavaBreakpointPropert
|
||||
result.set(JavaLineBreakpointType.class);
|
||||
}
|
||||
}
|
||||
else if (file.getUserData(PositionManager.LINE_NUMBERS_MAPPING_KEY) != null) {
|
||||
result.set(JavaLineBreakpointType.class);
|
||||
}
|
||||
}
|
||||
if (result.isNull()) {
|
||||
result.set(JavaMethodBreakpointType.class);
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.dataFlow.instructions.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -100,7 +101,9 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
|
||||
addInstruction(new ReturnInstruction(false, null));
|
||||
|
||||
new LiveVariablesAnalyzer(myCurrentFlow, myFactory).flushDeadVariablesOnStatementFinish();
|
||||
if (Registry.is("idea.dfa.live.variables.analysis")) {
|
||||
new LiveVariablesAnalyzer(myCurrentFlow, myFactory).flushDeadVariablesOnStatementFinish();
|
||||
}
|
||||
|
||||
return myCurrentFlow;
|
||||
}
|
||||
|
||||
@@ -222,24 +222,11 @@ public class DataFlowRunner {
|
||||
|
||||
protected DfaInstructionState[] acceptInstruction(InstructionVisitor visitor, DfaInstructionState instructionState) {
|
||||
Instruction instruction = instructionState.getInstruction();
|
||||
if (instruction instanceof MethodCallInstruction) {
|
||||
PsiCallExpression anchor = ((MethodCallInstruction)instruction).getCallExpression();
|
||||
if (anchor instanceof PsiNewExpression) {
|
||||
PsiAnonymousClass anonymousClass = ((PsiNewExpression)anchor).getAnonymousClass();
|
||||
if (anonymousClass != null) {
|
||||
registerNestedClosures(instructionState, anonymousClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (instruction instanceof LambdaInstruction) {
|
||||
PsiLambdaExpression lambdaExpression = ((LambdaInstruction)instruction).getLambdaExpression();
|
||||
registerNestedClosures(instructionState, lambdaExpression);
|
||||
}
|
||||
else if (instruction instanceof EmptyInstruction) {
|
||||
PsiElement anchor = ((EmptyInstruction)instruction).getAnchor();
|
||||
if (anchor instanceof PsiClass) {
|
||||
registerNestedClosures(instructionState, (PsiClass)anchor);
|
||||
}
|
||||
PsiElement closure = DfaUtil.getClosureInside(instruction);
|
||||
if (closure instanceof PsiClass) {
|
||||
registerNestedClosures(instructionState, (PsiClass)closure);
|
||||
} else if (closure instanceof PsiLambdaExpression) {
|
||||
registerNestedClosures(instructionState, (PsiLambdaExpression)closure);
|
||||
}
|
||||
|
||||
return instruction.accept(this, instructionState.getMemoryState(), visitor);
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.util.MultiValuesMap;
|
||||
@@ -113,6 +111,26 @@ public class DfaUtil {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static PsiElement getClosureInside(Instruction instruction) {
|
||||
if (instruction instanceof MethodCallInstruction) {
|
||||
PsiCallExpression anchor = ((MethodCallInstruction)instruction).getCallExpression();
|
||||
if (anchor instanceof PsiNewExpression) {
|
||||
return ((PsiNewExpression)anchor).getAnonymousClass();
|
||||
}
|
||||
}
|
||||
else if (instruction instanceof LambdaInstruction) {
|
||||
return ((LambdaInstruction)instruction).getLambdaExpression();
|
||||
}
|
||||
else if (instruction instanceof EmptyInstruction) {
|
||||
PsiElement anchor = ((EmptyInstruction)instruction).getAnchor();
|
||||
if (anchor instanceof PsiClass) {
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
|
||||
final Map<PsiElement, PlaceResult> myResults = ContainerUtil.newHashMap();
|
||||
|
||||
|
||||
@@ -21,10 +21,11 @@ import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FilteringIterator;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.*;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,6 +40,26 @@ public class LiveVariablesAnalyzer {
|
||||
private final Instruction[] myInstructions;
|
||||
private final MultiMap<Instruction, Instruction> myForwardMap;
|
||||
private final MultiMap<Instruction, Instruction> myBackwardMap;
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final FactoryMap<PsiElement, List<DfaVariableValue>> myClosureReads = new FactoryMap<PsiElement, List<DfaVariableValue>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
protected List<DfaVariableValue> create(PsiElement closure) {
|
||||
final Set<DfaVariableValue> result = ContainerUtil.newLinkedHashSet();
|
||||
closure.accept(new PsiRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
DfaValue value = myFactory.createValue((PsiReferenceExpression)element);
|
||||
if (value instanceof DfaVariableValue) {
|
||||
result.add((DfaVariableValue)value);
|
||||
}
|
||||
}
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
return ContainerUtil.newArrayList(result);
|
||||
}
|
||||
};
|
||||
|
||||
public LiveVariablesAnalyzer(ControlFlow flow, DfaValueFactory factory) {
|
||||
myFactory = factory;
|
||||
@@ -96,12 +117,36 @@ public class LiveVariablesAnalyzer {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static DfaVariableValue getWrittenVariable(Instruction instruction) {
|
||||
if (instruction instanceof AssignInstruction) {
|
||||
DfaValue value = ((AssignInstruction)instruction).getAssignedValue();
|
||||
return value instanceof DfaVariableValue ? (DfaVariableValue)value : null;
|
||||
}
|
||||
if (instruction instanceof FlushVariableInstruction) return ((FlushVariableInstruction)instruction).getVariable();
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<DfaVariableValue> getReadVariables(Instruction instruction) {
|
||||
if (instruction instanceof PushInstruction && !((PushInstruction)instruction).isReferenceWrite()) {
|
||||
DfaValue value = ((PushInstruction)instruction).getValue();
|
||||
if (value instanceof DfaVariableValue) {
|
||||
return Collections.singletonList((DfaVariableValue)value);
|
||||
}
|
||||
} else {
|
||||
PsiElement closure = DfaUtil.getClosureInside(instruction);
|
||||
if (closure != null) {
|
||||
return myClosureReads.get(closure);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private boolean isInterestingInstruction(Instruction instruction) {
|
||||
if (instruction == myInstructions[0]) return true;
|
||||
if (instruction instanceof PushInstruction) return ((PushInstruction)instruction).getValue() instanceof DfaVariableValue;
|
||||
if (instruction instanceof AssignInstruction) return ((AssignInstruction)instruction).getAssignedValue() != null;
|
||||
if (!getReadVariables(instruction).isEmpty() || getWrittenVariable(instruction) != null) return true;
|
||||
return instruction instanceof FinishElementInstruction ||
|
||||
instruction instanceof FlushVariableInstruction ||
|
||||
instruction instanceof GotoInstruction ||
|
||||
instruction instanceof ConditionalGotoInstruction ||
|
||||
instruction instanceof ReturnInstruction;
|
||||
@@ -124,34 +169,24 @@ public class LiveVariablesAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
if (instruction instanceof AssignInstruction) {
|
||||
DfaValue value = ((AssignInstruction)instruction).getAssignedValue();
|
||||
if (value instanceof DfaVariableValue) {
|
||||
liveVars = (BitSet)liveVars.clone();
|
||||
liveVars.clear(value.getID());
|
||||
for (DfaVariableValue var : myFactory.getVarFactory().getAllQualifiedBy((DfaVariableValue)value)) {
|
||||
liveVars.clear(var.getID());
|
||||
}
|
||||
DfaVariableValue written = getWrittenVariable(instruction);
|
||||
if (written != null) {
|
||||
liveVars = (BitSet)liveVars.clone();
|
||||
liveVars.clear(written.getID());
|
||||
for (DfaVariableValue var : myFactory.getVarFactory().getAllQualifiedBy(written)) {
|
||||
liveVars.clear(var.getID());
|
||||
}
|
||||
}
|
||||
|
||||
if (instruction instanceof PushInstruction) {
|
||||
DfaValue value = ((PushInstruction)instruction).getValue();
|
||||
if (value instanceof DfaVariableValue) {
|
||||
if (!((PushInstruction)instruction).isReferenceWrite() && !liveVars.get(value.getID())) {
|
||||
liveVars = (BitSet)liveVars.clone();
|
||||
} else {
|
||||
boolean cloned = false;
|
||||
for (DfaVariableValue value : getReadVariables(instruction)) {
|
||||
if (!liveVars.get(value.getID())) {
|
||||
if (!cloned) {
|
||||
liveVars = (BitSet)liveVars.clone();
|
||||
cloned = true;
|
||||
}
|
||||
liveVars.set(value.getID());
|
||||
}
|
||||
}
|
||||
} else if (instruction instanceof FlushVariableInstruction) {
|
||||
DfaVariableValue variable = ((FlushVariableInstruction)instruction).getVariable();
|
||||
if (variable != null) {
|
||||
liveVars = (BitSet)liveVars.clone();
|
||||
liveVars.clear(variable.getID());
|
||||
for (DfaVariableValue var : myFactory.getVarFactory().getAllQualifiedBy(variable)) {
|
||||
liveVars.clear(var.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return liveVars;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -60,7 +60,7 @@ public class JavaRegExpHost implements RegExpLanguageHost {
|
||||
|
||||
@Override
|
||||
public boolean supportsNamedGroupSyntax(RegExpGroup group) {
|
||||
if (group.isRubyNamedGroup()) {
|
||||
if (group.isNamedGroup()) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement(group);
|
||||
if (module != null) {
|
||||
final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Foo {
|
||||
|
||||
void foo(final @Nullable String s, String s2) {
|
||||
if (s2 == null) return;
|
||||
if (s == null) return;
|
||||
|
||||
System.out.println(s2);
|
||||
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
s.hashCode();
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -242,6 +242,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testManyContinuesNotComplex() { doTest(); }
|
||||
public void testFinallyNotComplex() { doTest(); }
|
||||
public void testFlushFurtherUnusedVariables() { doTest(); }
|
||||
public void testDontFlushVariablesUsedInClosures() { doTest(); }
|
||||
|
||||
public void testVariablesDiverge() { doTest(); }
|
||||
public void testMergeByNullability() { doTest(); }
|
||||
|
||||
@@ -15,19 +15,25 @@
|
||||
*/
|
||||
package com.intellij.index;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.impl.CurrentEditorProvider;
|
||||
import com.intellij.openapi.command.impl.UndoManagerImpl;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.SkipSlowTestLocally;
|
||||
@@ -47,7 +53,7 @@ import java.util.*;
|
||||
* Date: Dec 12, 2007
|
||||
*/
|
||||
@SkipSlowTestLocally
|
||||
public class IndexTest extends IdeaTestCase {
|
||||
public class IndexTest extends CodeInsightTestCase {
|
||||
|
||||
public void testUpdate() throws StorageException, IOException {
|
||||
final File storageFile = FileUtil.createTempFile("indextest", "storage");
|
||||
@@ -208,8 +214,7 @@ public class IndexTest extends IdeaTestCase {
|
||||
VfsUtil.saveText(vFile, "class Foo {}");
|
||||
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
|
||||
assertNotNull(facade.findClass("Foo", scope));
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -218,20 +223,20 @@ public class IndexTest extends IdeaTestCase {
|
||||
|
||||
Document document = FileDocumentManager.getInstance().getDocument(vFile);
|
||||
document.deleteString(0, document.getTextLength());
|
||||
assertNotNull(facade.findClass("Foo", scope));
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
|
||||
psiFile = null;
|
||||
PlatformTestUtil.tryGcSoftlyReachableObjects();
|
||||
assertNull(((PsiManagerEx)PsiManager.getInstance(getProject())).getFileManager().getCachedPsiFile(vFile));
|
||||
|
||||
PsiClass foo = facade.findClass("Foo", scope);
|
||||
PsiClass foo = myJavaFacade.findClass("Foo", scope);
|
||||
assertNotNull(foo);
|
||||
assertTrue(foo.isValid());
|
||||
assertEquals("class Foo {}", foo.getText());
|
||||
assertTrue(foo.isValid());
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
assertNull(facade.findClass("Foo", scope));
|
||||
assertNull(myJavaFacade.findClass("Foo", scope));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -244,8 +249,7 @@ public class IndexTest extends IdeaTestCase {
|
||||
VfsUtil.saveText(vFile, "");
|
||||
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
|
||||
assertNull(facade.findClass("Foo", scope));
|
||||
assertNull(myJavaFacade.findClass("Foo", scope));
|
||||
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -259,11 +263,11 @@ public class IndexTest extends IdeaTestCase {
|
||||
FileDocumentManager.getInstance().saveDocument(document);
|
||||
|
||||
assertTrue(count == PsiManager.getInstance(myProject).getModificationTracker().getModificationCount());
|
||||
assertNull(facade.findClass("Foo", scope));
|
||||
assertNull(myJavaFacade.findClass("Foo", scope));
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
assertNotNull(facade.findClass("Foo", scope));
|
||||
assertNotNull(facade.findClass("Foo", scope).getText());
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope).getText());
|
||||
// if Foo exists now, mod count should be different
|
||||
assertTrue(count != PsiManager.getInstance(myProject).getModificationTracker().getModificationCount());
|
||||
}
|
||||
@@ -303,9 +307,45 @@ public class IndexTest extends IdeaTestCase {
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
assertEquals(" Foo", file.getText());
|
||||
assertOneElement(PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithPlainTextWords("Foo"));
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testUndoToFileContentForUnsavedCommittedDocument() throws IOException {
|
||||
VirtualFile dir = getVirtualFile(createTempDirectory());
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, dir);
|
||||
|
||||
final VirtualFile vFile = createChildData(dir, "Foo.java");
|
||||
VfsUtil.saveText(vFile, "class Foo {}");
|
||||
((VirtualFileSystemEntry)vFile).setModificationStamp(0); // as unchanged file
|
||||
|
||||
final Document document = FileDocumentManager.getInstance().getDocument(vFile);
|
||||
assertTrue(document != null && document.getModificationStamp() == 0);
|
||||
final GlobalSearchScope scope = GlobalSearchScope.projectScope(myProject);
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
|
||||
WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.insertString(0, "import Bar;\n");
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
}
|
||||
});
|
||||
|
||||
final UndoManager undoManager = UndoManager.getInstance(getProject());
|
||||
final FileEditor selectedEditor = FileEditorManager.getInstance(myProject).openFile(vFile, false)[0];
|
||||
((UndoManagerImpl)undoManager).setEditorProvider(new CurrentEditorProvider() {
|
||||
@Override
|
||||
public FileEditor getCurrentEditor() {
|
||||
return selectedEditor;
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(undoManager.isUndoAvailable(selectedEditor));
|
||||
FileDocumentManager.getInstance().saveDocument(document);
|
||||
undoManager.undo(selectedEditor);
|
||||
|
||||
assertNotNull(myJavaFacade.findClass("Foo", scope));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,11 +132,11 @@ public class ProjectTreeSortingTest extends BaseProjectViewTestCase {
|
||||
((ProjectViewImpl)myProjectView).setFoldersAlwaysOnTop(false);
|
||||
assertTree("-foldersOnTop\n" +
|
||||
" a.java\n" +
|
||||
" +b.java\n" +
|
||||
" c.java\n" +
|
||||
" a.txt\n" +
|
||||
" c.txt\n" +
|
||||
" +b.java\n" +
|
||||
" +b.txt\n");
|
||||
" +b.txt\n"+
|
||||
" c.txt\n");
|
||||
}
|
||||
|
||||
public void testSortByTypeBetweenFilesAndFolders() throws Exception {
|
||||
@@ -156,11 +156,11 @@ public class ProjectTreeSortingTest extends BaseProjectViewTestCase {
|
||||
assertTree("-sortByTypeBetweenFilesAndFolders\n" +
|
||||
" a.java\n" +
|
||||
" b.java\n" +
|
||||
" +a.java_folder\n" +
|
||||
" +b.java_folder\n" +
|
||||
" a.txt\n" +
|
||||
" b.txt\n" +
|
||||
" +a.java_folder\n" +
|
||||
" +a_folder\n" +
|
||||
" +b.java_folder\n" +
|
||||
" +b_folder\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.intellij.json.formatter;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.json.JsonElementTypes;
|
||||
import com.intellij.json.JsonLanguage;
|
||||
import com.intellij.json.JsonParserDefinition;
|
||||
import com.intellij.json.psi.JsonArray;
|
||||
import com.intellij.json.psi.JsonObject;
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
@@ -23,18 +21,19 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.json.JsonParserDefinition.JSON_BRACES;
|
||||
import static com.intellij.json.JsonParserDefinition.JSON_BRACKETS;
|
||||
import static com.intellij.json.JsonElementTypes.*;
|
||||
import static com.intellij.json.JsonParserDefinition.*;
|
||||
import static com.intellij.json.formatter.JsonCodeStyleSettings.PropertyAlignment.ALIGN_ON_COLON;
|
||||
import static com.intellij.json.formatter.JsonCodeStyleSettings.PropertyAlignment.ALIGN_ON_VALUE;
|
||||
import static com.intellij.json.psi.JsonPsiUtil.hasElementType;
|
||||
|
||||
/**
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class JsonBlock implements ASTBlock {
|
||||
private static final TokenSet OPEN_BRACES = TokenSet.create(JsonElementTypes.L_BRACKET, JsonElementTypes.L_CURLY);
|
||||
private static final TokenSet CLOSE_BRACES = TokenSet.create(JsonElementTypes.R_BRACKET, JsonElementTypes.R_CURLY);
|
||||
private static final TokenSet BRACES = TokenSet.orSet(OPEN_BRACES, CLOSE_BRACES);
|
||||
private static final TokenSet JSON_OPEN_BRACES = TokenSet.create(L_BRACKET, L_CURLY);
|
||||
private static final TokenSet JSON_CLOSE_BRACES = TokenSet.create(R_BRACKET, R_CURLY);
|
||||
private static final TokenSet JSON_ALL_BRACES = TokenSet.orSet(JSON_OPEN_BRACES, JSON_CLOSE_BRACES);
|
||||
|
||||
private final JsonBlock myParent;
|
||||
|
||||
@@ -48,8 +47,6 @@ public class JsonBlock implements ASTBlock {
|
||||
// lazy initialized on first call to #getSubBlocks()
|
||||
private List<Block> mySubBlocks = null;
|
||||
|
||||
private final Alignment myChildAlignment = Alignment.createAlignment();
|
||||
|
||||
private final Alignment myPropertyValueAlignment;
|
||||
private final Wrap myChildWrap;
|
||||
|
||||
@@ -111,28 +108,35 @@ public class JsonBlock implements ASTBlock {
|
||||
}
|
||||
|
||||
private Block makeSubBlock(@NotNull ASTNode childNode) {
|
||||
final IElementType childNodeType = childNode.getElementType();
|
||||
|
||||
Indent indent = Indent.getNoneIndent();
|
||||
Alignment alignment = null;
|
||||
Wrap wrap = null;
|
||||
|
||||
JsonCodeStyleSettings customSettings = getCustomSettings();
|
||||
if (isContainer() && childNodeType != JsonElementTypes.COMMA && !BRACES.contains(childNodeType)) {
|
||||
assert myChildWrap != null && myChildAlignment != null;
|
||||
wrap = myChildWrap;
|
||||
alignment = myChildAlignment;
|
||||
indent = Indent.getNormalIndent();
|
||||
final JsonCodeStyleSettings customSettings = getCustomSettings();
|
||||
if (hasElementType(myNode, JSON_CONTAINERS)) {
|
||||
if (!hasElementType(childNode, COMMA) && !hasElementType(childNode, JSON_ALL_BRACES)) {
|
||||
assert myChildWrap != null;
|
||||
wrap = myChildWrap;
|
||||
indent = Indent.getNormalIndent();
|
||||
}
|
||||
else if (hasElementType(childNode, JSON_OPEN_BRACES)) {
|
||||
if (JsonPsiUtil.isPropertyValue(myPsiElement) && customSettings.PROPERTY_ALIGNMENT == ALIGN_ON_VALUE) {
|
||||
// WEB-13587 Align compound values on opening brace/bracket, not the whole block
|
||||
assert myParent != null && myParent.myParent != null && myParent.myParent.myPropertyValueAlignment != null;
|
||||
alignment = myParent.myParent.myPropertyValueAlignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle properties alignment
|
||||
else if (myNode.getElementType() == JsonElementTypes.PROPERTY) {
|
||||
assert myParent.myNode.getElementType() == JsonElementTypes.OBJECT;
|
||||
assert myParent.myPropertyValueAlignment != null;
|
||||
if (childNode.getElementType() == JsonElementTypes.COLON && customSettings.PROPERTY_ALIGNMENT == ALIGN_ON_COLON) {
|
||||
else if (hasElementType(myNode, PROPERTY) ) {
|
||||
assert myParent != null && myParent.myPropertyValueAlignment != null;
|
||||
if (hasElementType(childNode, COLON) && customSettings.PROPERTY_ALIGNMENT == ALIGN_ON_COLON) {
|
||||
alignment = myParent.myPropertyValueAlignment;
|
||||
}
|
||||
else if (JsonPsiUtil.isPropertyValue(childNode.getPsi()) && customSettings.PROPERTY_ALIGNMENT == ALIGN_ON_VALUE) {
|
||||
alignment = myParent.myPropertyValueAlignment;
|
||||
if (!hasElementType(childNode, JSON_CONTAINERS)) {
|
||||
alignment = myParent.myPropertyValueAlignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new JsonBlock(this, childNode, mySettings, alignment, indent, wrap);
|
||||
@@ -160,17 +164,17 @@ public class JsonBlock implements ASTBlock {
|
||||
@Override
|
||||
public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) {
|
||||
final CommonCodeStyleSettings commonSettings = getCommonSettings();
|
||||
final IElementType leftChildType = child1 instanceof JsonBlock ? ((JsonBlock)child1).myNode.getElementType() : null;
|
||||
final IElementType rightChildType = child2 instanceof JsonBlock ? ((JsonBlock)child2).myNode.getElementType() : null;
|
||||
final ASTNode leftChild = child1 instanceof JsonBlock ? ((JsonBlock)child1).myNode : null;
|
||||
final ASTNode rightChild = child2 instanceof JsonBlock ? ((JsonBlock)child2).myNode : null;
|
||||
// This causes braces/brackets to be on their own lines if whole object/array spans several lines.
|
||||
if (leftChildType != null && rightChildType != null) {
|
||||
if (JSON_BRACES.contains(leftChildType) ^ JSON_BRACES.contains(rightChildType)) {
|
||||
if (leftChild != null && rightChild != null) {
|
||||
if (hasElementType(leftChild, JSON_BRACES) ^ hasElementType(rightChild, JSON_BRACES)) {
|
||||
final int numSpaces = commonSettings.SPACE_WITHIN_BRACES ? 1 : 0;
|
||||
return Spacing.createDependentLFSpacing(numSpaces, numSpaces, myNode.getTextRange(),
|
||||
commonSettings.KEEP_LINE_BREAKS,
|
||||
commonSettings.KEEP_BLANK_LINES_IN_CODE);
|
||||
}
|
||||
else if (JSON_BRACKETS.contains(leftChildType) ^ JSON_BRACKETS.contains(rightChildType)) {
|
||||
else if (hasElementType(leftChild, JSON_BRACKETS) ^ hasElementType(rightChild, JSON_BRACKETS)) {
|
||||
final int numSpaces = commonSettings.SPACE_WITHIN_BRACKETS ? 1 : 0;
|
||||
return Spacing.createDependentLFSpacing(numSpaces, numSpaces, myNode.getTextRange(),
|
||||
commonSettings.KEEP_LINE_BREAKS,
|
||||
@@ -183,8 +187,11 @@ public class JsonBlock implements ASTBlock {
|
||||
@NotNull
|
||||
@Override
|
||||
public ChildAttributes getChildAttributes(int newChildIndex) {
|
||||
if (isContainer()) {
|
||||
return new ChildAttributes(Indent.getNormalIndent(), myChildAlignment);
|
||||
if (hasElementType(myNode, JSON_CONTAINERS)) {
|
||||
// WEB-13675: For some reason including alignment in child attributes causes
|
||||
// indents to consist solely of spaces when both USE_TABS and SMART_TAB
|
||||
// options are enabled.
|
||||
return new ChildAttributes(Indent.getNormalIndent(), null);
|
||||
}
|
||||
// Will use continuation indent for cases like { "foo"<caret> }
|
||||
return new ChildAttributes(null, null);
|
||||
@@ -192,15 +199,14 @@ public class JsonBlock implements ASTBlock {
|
||||
|
||||
@Override
|
||||
public boolean isIncomplete() {
|
||||
IElementType nodeType = myNode.getElementType();
|
||||
ASTNode lastChildNode = myNode.getLastChildNode();
|
||||
if (nodeType == JsonElementTypes.OBJECT) {
|
||||
return lastChildNode != null && lastChildNode.getElementType() != JsonElementTypes.R_CURLY;
|
||||
final ASTNode lastChildNode = myNode.getLastChildNode();
|
||||
if (hasElementType(myNode, OBJECT)) {
|
||||
return lastChildNode != null && lastChildNode.getElementType() != R_CURLY;
|
||||
}
|
||||
else if (nodeType == JsonElementTypes.ARRAY) {
|
||||
return lastChildNode != null && lastChildNode.getElementType() != JsonElementTypes.R_BRACKET;
|
||||
else if (hasElementType(myNode, ARRAY)) {
|
||||
return lastChildNode != null && lastChildNode.getElementType() != R_BRACKET;
|
||||
}
|
||||
else if (myPsiElement instanceof JsonProperty) {
|
||||
else if (hasElementType(myNode, PROPERTY)) {
|
||||
return ((JsonProperty)myPsiElement).getValue() == null;
|
||||
}
|
||||
return false;
|
||||
@@ -215,10 +221,6 @@ public class JsonBlock implements ASTBlock {
|
||||
return node.getElementType() == TokenType.WHITE_SPACE || node.getTextLength() == 0;
|
||||
}
|
||||
|
||||
private boolean isContainer() {
|
||||
return JsonParserDefinition.JSON_CONTAINERS.contains(myNode.getElementType());
|
||||
}
|
||||
|
||||
private JsonCodeStyleSettings getCustomSettings() {
|
||||
return mySettings.getCustomSettings(JsonCodeStyleSettings.class);
|
||||
}
|
||||
|
||||
@@ -23,13 +23,16 @@ import java.awt.event.ItemListener;
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class JsonCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
public static final String SAMPLE = "{\n" +
|
||||
" \"longKeyName\": true,\n" +
|
||||
" \"short\": false,\n" +
|
||||
"\n" +
|
||||
" \"group2-longKeyName\": null,\n" +
|
||||
" \"group2-short\": 42\n" +
|
||||
"}";
|
||||
public static final String ALIGNMENT_SAMPLE = "{\n" +
|
||||
" \"foo\": {\n" +
|
||||
" \"bar\": true,\n" +
|
||||
" \"baz\": false\n" +
|
||||
" },\n" +
|
||||
" \"quux\": [\n" +
|
||||
" 1, 2.0, 3e0, 4.0e0\n" +
|
||||
" ],\n" +
|
||||
" \"longPropertyName\": null\n" +
|
||||
"}";
|
||||
|
||||
private JComboBox myPropertiesAlignmentCombo;
|
||||
private JPanel myPreviewPanel;
|
||||
@@ -59,7 +62,6 @@ public class JsonCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,7 +84,7 @@ public class JsonCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getPreviewText() {
|
||||
return SAMPLE;
|
||||
return ALIGNMENT_SAMPLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.json.JsonParserDefinition.JSON_COMMENTARIES;
|
||||
@@ -86,4 +87,35 @@ public class JsonPsiUtil {
|
||||
}
|
||||
return lastSeen.getPsi();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that element type of the given AST node belongs to the token set.
|
||||
* <p/>
|
||||
* It slightly less verbose than {@code set.contains(node.getElementType())} and overloaded methods with the same name
|
||||
* allow check ASTNode/PsiElement against both concrete element types and token sets in uniform way.
|
||||
*/
|
||||
public static boolean hasElementType(@NotNull ASTNode node, @NotNull TokenSet set) {
|
||||
return set.contains(node.getElementType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #hasElementType(com.intellij.lang.ASTNode, com.intellij.psi.tree.TokenSet)
|
||||
*/
|
||||
public static boolean hasElementType(@NotNull ASTNode node, IElementType... types) {
|
||||
return hasElementType(node, TokenSet.create(types));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #hasElementType(com.intellij.lang.ASTNode, com.intellij.psi.tree.TokenSet)
|
||||
*/
|
||||
public static boolean hasElementType(@NotNull PsiElement element, @NotNull TokenSet set) {
|
||||
return element.getNode() != null && hasElementType(element.getNode(), set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #hasElementType(com.intellij.lang.ASTNode, com.intellij.psi.tree.IElementType...)
|
||||
*/
|
||||
public static boolean hasElementType(@NotNull PsiElement element, IElementType... types) {
|
||||
return element.getNode() != null && hasElementType(element.getNode(), types);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.intellij.json;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -37,4 +40,22 @@ public class JsonEditingTest extends JsonTestCase {
|
||||
public void testNormalIndentAfterPropertyWithoutComma() {
|
||||
doTest("\n");
|
||||
}
|
||||
|
||||
// WEB-13675
|
||||
public void testIndentWithTabsWhenSmartTabEnabled() {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myFixture.getProject());
|
||||
CommonCodeStyleSettings.IndentOptions indentOptions = settings.getCommonSettings(JsonLanguage.INSTANCE).getIndentOptions();
|
||||
assertNotNull(indentOptions);
|
||||
CommonCodeStyleSettings.IndentOptions oldSettings = (CommonCodeStyleSettings.IndentOptions)indentOptions.clone();
|
||||
indentOptions.TAB_SIZE = 4;
|
||||
indentOptions.INDENT_SIZE = 4;
|
||||
indentOptions.USE_TAB_CHARACTER = true;
|
||||
indentOptions.SMART_TABS = true;
|
||||
try {
|
||||
doTest("\n\"baz\"");
|
||||
}
|
||||
finally {
|
||||
indentOptions.copyFrom(oldSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"foo": true,
|
||||
"bar": false,
|
||||
"baz"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"foo": true,
|
||||
"bar": false,<caret>
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"a": 1,
|
||||
"aaa": 2,
|
||||
"aaaaa": 3
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~3.7",
|
||||
"phpunit/phpunit-selenium": "@stable",
|
||||
"phpunit/phpunit-story": "@stable",
|
||||
"phpunit/dbunit": "@stable"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DreamFactory\\Yii\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "1.5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"a" : 1,
|
||||
"aaa" : 2,
|
||||
"aaaaa": 3
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "~3.7",
|
||||
"phpunit/phpunit-selenium": "@stable",
|
||||
"phpunit/phpunit-story" : "@stable",
|
||||
"phpunit/dbunit" : "@stable"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload" : {
|
||||
"psr-4": {
|
||||
"DreamFactory\\Yii\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra" : {
|
||||
"branch-alias": {
|
||||
"dev-develop": "1.5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"a": 1,
|
||||
"aaa": 2,
|
||||
"aaaaa": 3
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~3.7",
|
||||
"phpunit/phpunit-selenium": "@stable",
|
||||
"phpunit/phpunit-story": "@stable",
|
||||
"phpunit/dbunit": "@stable"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DreamFactory\\Yii\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "1.5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"a": 1,
|
||||
"aaa": 2,
|
||||
"aaaaa": 3
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~3.7",
|
||||
"phpunit/phpunit-selenium": "@stable",
|
||||
"phpunit/phpunit-story": "@stable",
|
||||
"phpunit/dbunit": "@stable"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DreamFactory\\Yii\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-develop": "1.5.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
[
|
||||
1, <selection>[2], [true,
|
||||
false</selection>],
|
||||
1, <selection>[2],
|
||||
[
|
||||
true,
|
||||
false
|
||||
]</selection>,
|
||||
null
|
||||
]
|
||||
@@ -1,5 +1,8 @@
|
||||
[
|
||||
null,
|
||||
1, [2], [true,
|
||||
false]
|
||||
1, [2],
|
||||
[
|
||||
true,
|
||||
false
|
||||
]
|
||||
]
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"foo": <selection>false, "bar": 42,
|
||||
"baz": [1, 2,
|
||||
3</selection>],
|
||||
"foo": false,
|
||||
"bar": <selection>42,
|
||||
"baz": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]</selection>,
|
||||
"quux": null
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"foo": false,
|
||||
"quux": null,
|
||||
"foo": false, "bar": 42,
|
||||
"baz": [1, 2,
|
||||
3]
|
||||
"bar": 42,
|
||||
"baz": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
@@ -35,7 +35,10 @@ public class ComponentSerializationUtil {
|
||||
public static <S> void loadComponentState(@NotNull PersistentStateComponent<S> configuration, @Nullable Element element) {
|
||||
if (element != null) {
|
||||
Class<S> stateClass = getStateClass(configuration.getClass());
|
||||
configuration.loadState(XmlSerializer.deserialize(element, stateClass));
|
||||
S state = XmlSerializer.deserialize(element, stateClass);
|
||||
if (state != null) {
|
||||
configuration.loadState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +493,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
throwGuardedFragment(marker, offset, null, s.toString());
|
||||
}
|
||||
|
||||
updateText(myText.insert(offset, ImmutableText.valueOf(s)), offset, null, s, false, LocalTimeCounter.currentTime());
|
||||
myText = myText.ensureChunked();
|
||||
ImmutableText newText = myText.insert(offset, ImmutableText.valueOf(s));
|
||||
updateText(newText, offset, null, newText.subtext(offset, offset + s.length()), false, LocalTimeCounter.currentTime());
|
||||
trimToSize();
|
||||
}
|
||||
|
||||
@@ -511,14 +513,13 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
if (!isWritable()) throw new ReadOnlyModificationException(this);
|
||||
if (startOffset == endOffset) return;
|
||||
|
||||
CharSequence sToDelete = myText.subSequence(startOffset, endOffset);
|
||||
|
||||
RangeMarker marker = getRangeGuard(startOffset, endOffset);
|
||||
if (marker != null) {
|
||||
throwGuardedFragment(marker, startOffset, sToDelete.toString(), null);
|
||||
throwGuardedFragment(marker, startOffset, myText.subSequence(startOffset, endOffset).toString(), null);
|
||||
}
|
||||
|
||||
updateText(myText.delete(startOffset, endOffset), startOffset, sToDelete, null, false, LocalTimeCounter.currentTime());
|
||||
myText = myText.ensureChunked();
|
||||
updateText(myText.delete(startOffset, endOffset), startOffset, myText.subtext(startOffset, endOffset), null, false, LocalTimeCounter.currentTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -582,7 +583,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
}
|
||||
|
||||
CharSequence changedPart = s.subSequence(newStartInString, newEndInString);
|
||||
CharSequence sToDelete = myText.subSequence(startOffset, endOffset);
|
||||
CharSequence sToDelete = myText.subtext(startOffset, endOffset);
|
||||
RangeMarker guard = getRangeGuard(startOffset, endOffset);
|
||||
if (guard != null) {
|
||||
throwGuardedFragment(guard, startOffset, sToDelete.toString(), changedPart.toString());
|
||||
@@ -593,7 +594,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
|
||||
newText = (ImmutableText)s;
|
||||
}
|
||||
else {
|
||||
myText = myText.ensureChunked();
|
||||
newText = myText.delete(startOffset, endOffset).insert(startOffset, changedPart);
|
||||
changedPart = newText.subtext(startOffset, startOffset + changedPart.length());
|
||||
}
|
||||
updateText(newText, startOffset, sToDelete, changedPart, wholeTextReplaced, newModificationStamp);
|
||||
trimToSize();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.dupLocator;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
@@ -22,19 +21,13 @@ import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: db
|
||||
* Date: Apr 8, 2004
|
||||
* Time: 2:47:43 PM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
@State(
|
||||
name="DuplocatorSettings",
|
||||
name = "DuplocatorSettings",
|
||||
storages = {
|
||||
@Storage(
|
||||
file = StoragePathMacros.APP_CONFIG + "/other.xml"
|
||||
)}
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/duplocatorSettings.xml")
|
||||
},
|
||||
storageChooser = LastStorageChooserForWrite.class
|
||||
)
|
||||
public class DuplocatorSettings implements PersistentStateComponent<DuplocatorSettings> {
|
||||
public boolean DISTINGUISH_VARIABLES = false;
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizable;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -17,14 +17,12 @@ import java.util.Map;
|
||||
*/
|
||||
@State(
|
||||
name = "MultiLanguageDuplocatorSettings",
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/duplocatorSettings.xml")
|
||||
}
|
||||
storages = @Storage(file = StoragePathMacros.APP_CONFIG + "/duplocatorSettings.xml")
|
||||
)
|
||||
public class MultilanguageDuplocatorSettings implements PersistentStateComponent<Element> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.dupLocator.MultiLanguageDuplocatorSettings");
|
||||
|
||||
private final Map<String, ExternalizableDuplocatorState> mySettingsMap = new HashMap<String, ExternalizableDuplocatorState>();
|
||||
private final Map<String, ExternalizableDuplocatorState> mySettingsMap = new LinkedHashMap<String, ExternalizableDuplocatorState>();
|
||||
|
||||
public static MultilanguageDuplocatorSettings getInstance() {
|
||||
return ServiceManager.getService(MultilanguageDuplocatorSettings.class);
|
||||
|
||||
|
After Width: | Height: | Size: 128 B |
|
After Width: | Height: | Size: 212 B |
|
After Width: | Height: | Size: 212 B |
|
After Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 630 B |
|
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 178 B |
|
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 263 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 219 B |
|
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 372 B |
|
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 153 B |
@@ -256,9 +256,6 @@ public class DetectionExcludesConfigurable implements Configurable {
|
||||
|
||||
@Nullable
|
||||
private ExcludesConfigurationState computeState() {
|
||||
if (myModel.getItems().isEmpty() && myEnabledDetectionCheckBox.isSelected()) {
|
||||
return null;
|
||||
}
|
||||
final ExcludesConfigurationState state = new ExcludesConfigurationState();
|
||||
state.setDetectionEnabled(myEnabledDetectionCheckBox.isSelected());
|
||||
for (ExcludeListItem item : myModel.getItems()) {
|
||||
@@ -278,22 +275,20 @@ public class DetectionExcludesConfigurable implements Configurable {
|
||||
public void reset() {
|
||||
myModel.clear();
|
||||
final ExcludesConfigurationState state = myConfiguration.getActualState();
|
||||
myEnabledDetectionCheckBox.setSelected(state == null || state.isDetectionEnabled());
|
||||
if (state != null) {
|
||||
for (String typeId : state.getFrameworkTypes()) {
|
||||
final FrameworkType frameworkType = FrameworkDetectorRegistry.getInstance().findFrameworkType(typeId);
|
||||
myModel.add(frameworkType != null ? new ValidExcludeListItem(frameworkType, null) : new InvalidExcludeListItem(typeId, null));
|
||||
myEnabledDetectionCheckBox.setSelected(state.isDetectionEnabled());
|
||||
for (String typeId : state.getFrameworkTypes()) {
|
||||
final FrameworkType frameworkType = FrameworkDetectorRegistry.getInstance().findFrameworkType(typeId);
|
||||
myModel.add(frameworkType != null ? new ValidExcludeListItem(frameworkType, null) : new InvalidExcludeListItem(typeId, null));
|
||||
}
|
||||
for (ExcludedFileState fileState : state.getFiles()) {
|
||||
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(fileState.getUrl());
|
||||
final String typeId = fileState.getFrameworkType();
|
||||
if (typeId == null) {
|
||||
myModel.add(file != null ? new ValidExcludeListItem(null, file) : new InvalidExcludeListItem(null, fileState.getUrl()));
|
||||
}
|
||||
for (ExcludedFileState fileState : state.getFiles()) {
|
||||
VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(fileState.getUrl());
|
||||
final String typeId = fileState.getFrameworkType();
|
||||
if (typeId == null) {
|
||||
myModel.add(file != null ? new ValidExcludeListItem(null, file) : new InvalidExcludeListItem(null, fileState.getUrl()));
|
||||
}
|
||||
else {
|
||||
final FrameworkType frameworkType = FrameworkDetectorRegistry.getInstance().findFrameworkType(typeId);
|
||||
myModel.add(frameworkType != null && file != null? new ValidExcludeListItem(frameworkType, file) : new InvalidExcludeListItem(typeId, fileState.getUrl()));
|
||||
}
|
||||
else {
|
||||
final FrameworkType frameworkType = FrameworkDetectorRegistry.getInstance().findFrameworkType(typeId);
|
||||
myModel.add(frameworkType != null && file != null? new ValidExcludeListItem(frameworkType, file) : new InvalidExcludeListItem(typeId, fileState.getUrl()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,12 +185,9 @@ public class DetectionExcludesConfigurationImpl extends DetectionExcludesConfigu
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
public ExcludesConfigurationState getActualState() {
|
||||
ensureOldSettingsLoaded();
|
||||
if (myExcludedFiles.isEmpty() && myExcludedFrameworks.isEmpty() && myDetectionEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ExcludesConfigurationState state = new ExcludesConfigurationState();
|
||||
state.setDetectionEnabled(myDetectionEnabled);
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.platform.ModuleAttachProcessor;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
@@ -29,7 +26,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
@State(
|
||||
name = "RecentDirectoryProjectsManager",
|
||||
storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml", roamingType = RoamingType.DISABLED)}
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/recentProjectDirectories.xml", roamingType = RoamingType.DISABLED)
|
||||
},
|
||||
storageChooser = LastStorageChooserForWrite.class
|
||||
)
|
||||
public class RecentDirectoryProjectsManagerEx extends RecentDirectoryProjectsManager {
|
||||
public RecentDirectoryProjectsManagerEx(MessageBus messageBus) {
|
||||
|
||||
@@ -318,6 +318,14 @@ public class PsiDirectoryNode extends BasePsiNode<PsiDirectory> implements Navig
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparable getTypeSortKey() {
|
||||
VirtualFile file = getVirtualFile();
|
||||
if (file == null) return null;
|
||||
String extension = file.getExtension();
|
||||
return extension == null ? null : new PsiFileNode.ExtensionSortKey(extension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedNameSortKey() {
|
||||
final PsiDirectoryFactory factory = PsiDirectoryFactory.getInstance(getProject());
|
||||
|
||||
@@ -89,34 +89,22 @@ public abstract class AbstractGithubTagDownloadedProjectGenerator extends WebPro
|
||||
@NotNull File extractToDir,
|
||||
@NotNull GithubTagInfo tag) throws GeneratorException {
|
||||
File zipArchiveFile = getCacheFile(tag);
|
||||
boolean brokenZip = true;
|
||||
boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
if (!unitTestMode && zipArchiveFile.isFile()) {
|
||||
String primaryUrl = getPrimaryZipArchiveUrlForDownload(tag);
|
||||
boolean downloaded = false;
|
||||
if (primaryUrl != null) {
|
||||
try {
|
||||
ZipUtil.unzipWithProgressSynchronously(project, getTitle(), zipArchiveFile, extractToDir, true);
|
||||
brokenZip = false;
|
||||
}
|
||||
catch (GeneratorException ignored) {
|
||||
downloadAndUnzip(project, primaryUrl, zipArchiveFile, extractToDir, false);
|
||||
downloaded = true;
|
||||
} catch (GeneratorException e) {
|
||||
LOG.info("Can't download " + primaryUrl, e);
|
||||
FileUtil.delete(zipArchiveFile);
|
||||
}
|
||||
}
|
||||
if (brokenZip) {
|
||||
String primaryUrl = getPrimaryZipArchiveUrlForDownload(tag);
|
||||
boolean downloaded = false;
|
||||
if (primaryUrl != null) {
|
||||
try {
|
||||
downloadAndUnzip(project, primaryUrl, zipArchiveFile, extractToDir, false);
|
||||
downloaded = true;
|
||||
} catch (GeneratorException e) {
|
||||
LOG.info("Can't download " + primaryUrl, e);
|
||||
FileUtil.delete(zipArchiveFile);
|
||||
}
|
||||
}
|
||||
if (!downloaded) {
|
||||
if (unitTestMode) {
|
||||
throw new GeneratorException("Download " + tag.getZipballUrl() + " is skipped in unit test mode");
|
||||
}
|
||||
downloadAndUnzip(project, tag.getZipballUrl(), zipArchiveFile, extractToDir, true);
|
||||
if (!downloaded) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
throw new GeneratorException("Download " + tag.getZipballUrl() + " is skipped in unit test mode");
|
||||
}
|
||||
downloadAndUnzip(project, tag.getZipballUrl(), zipArchiveFile, extractToDir, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.openapi.components.*;
|
||||
@@ -25,9 +24,10 @@ import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
@State(
|
||||
name = "BaseRefactoringSettings",
|
||||
storages = {
|
||||
@Storage(
|
||||
file = StoragePathMacros.APP_CONFIG + "/other.xml"
|
||||
)}
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/baseRefactoring.xml")
|
||||
},
|
||||
storageChooser = LastStorageChooserForWrite.class
|
||||
)
|
||||
public class RefactoringSettings implements PersistentStateComponent<RefactoringSettings> {
|
||||
public static RefactoringSettings getInstance() {
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil;
|
||||
import com.intellij.util.xmlb.annotations.OptionTag;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -38,7 +41,6 @@ public class GeneralSettings implements PersistentStateComponent<GeneralSettings
|
||||
|
||||
private String myBrowserPath = BrowserUtil.getDefaultAlternativeBrowserPath();
|
||||
private boolean myShowTipsOnStartup = true;
|
||||
private int myLastTip = 0;
|
||||
private boolean myReopenLastProject = true;
|
||||
private boolean mySyncOnFrameActivation = true;
|
||||
private boolean mySaveOnFrameDeactivation = true;
|
||||
@@ -107,12 +109,13 @@ public class GeneralSettings implements PersistentStateComponent<GeneralSettings
|
||||
myShowTipsOnStartup = b;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public int getLastTip() {
|
||||
return myLastTip;
|
||||
return StringUtil.parseInt(PropertiesComponent.getInstance().getValue("lastTip"), 0);
|
||||
}
|
||||
|
||||
public void setLastTip(int i) {
|
||||
myLastTip = i;
|
||||
PropertiesComponent.getInstance().setValue("lastTip", Integer.toString(i), "0");
|
||||
}
|
||||
|
||||
public boolean isReopenLastProject() {
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.ui.components.JBTextField;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.ui.MacUIUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -47,7 +48,7 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
public static final Border EDITOR_BORDER = new MacComboBoxEditorBorder(false);
|
||||
public static final Border DISABLED_EDITOR_BORDER = new MacComboBoxEditorBorder(true);
|
||||
|
||||
private JBTextField myField;
|
||||
@NotNull private final JBTextField myField;
|
||||
private Object oldValue;
|
||||
|
||||
public FixedComboBoxEditor() {
|
||||
@@ -60,7 +61,8 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
|
||||
}
|
||||
}
|
||||
|
||||
protected JTextField getField() {
|
||||
@NotNull
|
||||
public JBTextField getField() {
|
||||
return myField;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
@@ -252,15 +253,14 @@ public class DimensionService implements PersistentStateComponent<Element> {
|
||||
}
|
||||
|
||||
JFrame frame = null;
|
||||
if (project == null) {
|
||||
final Component owner = IdeFocusManager.findInstance().getFocusOwner();
|
||||
if (owner != null) {
|
||||
frame = UIUtil.getParentOfType(JFrame.class, owner);
|
||||
}
|
||||
if (frame == null) {
|
||||
frame = WindowManager.getInstance().findVisibleFrame();
|
||||
}
|
||||
} else {
|
||||
final Component owner = IdeFocusManager.findInstance().getFocusOwner();
|
||||
if (owner != null) {
|
||||
frame = UIUtil.getParentOfType(JFrame.class, owner);
|
||||
}
|
||||
if (frame == null) {
|
||||
frame = WindowManager.getInstance().findVisibleFrame();
|
||||
}
|
||||
if (project != null && (frame == null || (frame instanceof IdeFrame && project != ((IdeFrame)frame).getProject()))) {
|
||||
frame = WindowManager.getInstance().getFrame(project);
|
||||
}
|
||||
Rectangle screen = new Rectangle(0, 0, 0, 0);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="503" height="400"/>
|
||||
<xy x="20" y="20" width="606" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -56,7 +56,7 @@
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Accept &automatically"/>
|
||||
<text value="Accept non-trusted certificates &automatically"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide;
|
||||
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.components.StoragePathMacros;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
@@ -34,7 +31,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
@State(
|
||||
name = "RecentDirectoryProjectsManager",
|
||||
storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml", roamingType = RoamingType.DISABLED)}
|
||||
storages = {
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/recentProjectDirectories.xml", roamingType = RoamingType.DISABLED)
|
||||
},
|
||||
storageChooser = LastStorageChooserForWrite.class
|
||||
)
|
||||
public class RecentDirectoryProjectsManager extends RecentProjectsManagerBase {
|
||||
public RecentDirectoryProjectsManager(MessageBus messageBus) {
|
||||
|
||||
@@ -199,7 +199,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border {
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
final Container parent = c.getParent();
|
||||
if (parent != null) {
|
||||
g.setColor(parent.getBackground());
|
||||
g.setColor(isTableCellEditor(c) && editor != null ? editor.getBackground() : parent.getBackground());
|
||||
g.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
Rectangle r = rectangleForCurrentValue();
|
||||
@@ -212,7 +212,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border {
|
||||
}
|
||||
|
||||
private static boolean isTableCellEditor(JComponent c) {
|
||||
return Boolean.TRUE.equals(c.getClientProperty("JComboBox.isTableCellEditor"));
|
||||
return Boolean.TRUE.equals(c.getClientProperty("JComboBox.isTableCellEditor")) || c.getParent() instanceof JTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,9 @@ import java.awt.*;
|
||||
public class DarculaEditorTextFieldBorder implements Border {
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
if (isComboBoxEditor(c) || isCellEditor(c)) {
|
||||
if (isComboBoxEditor(c) /*|| isCellEditor(c)*/) {
|
||||
g.setColor(c.getBackground());
|
||||
g.fillRect(x, y, width, height);
|
||||
return;
|
||||
}
|
||||
final EditorTextField textField = UIUtil.getParentOfType(EditorTextField.class, c);
|
||||
@@ -65,8 +67,8 @@ public class DarculaEditorTextFieldBorder implements Border {
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
if (isComboBoxEditor(c) || isCellEditor(c)) {
|
||||
return new InsetsUIResource(0,0,0,0);
|
||||
if (isComboBoxEditor(c) /*|| isCellEditor(c)*/) {
|
||||
return new InsetsUIResource(2,3,2,3);
|
||||
}
|
||||
return new InsetsUIResource(6, 7, 6, 7);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -44,13 +45,13 @@ public class TipPanel extends JPanel {
|
||||
setLayout(new BorderLayout());
|
||||
JLabel jlabel = new JLabel(AllIcons.General.Tip);
|
||||
jlabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
|
||||
JLabel jlabel1 = new JLabel(IdeBundle.message("label.did.you.know"));
|
||||
Font font = jlabel1.getFont();
|
||||
jlabel1.setFont(font.deriveFont(Font.PLAIN, font.getSize() + 4));
|
||||
JLabel label1 = new JLabel(IdeBundle.message("label.did.you.know"));
|
||||
Font font = label1.getFont();
|
||||
label1.setFont(font.deriveFont(Font.PLAIN, font.getSize() + 4));
|
||||
JPanel jpanel = new JPanel();
|
||||
jpanel.setLayout(new BorderLayout());
|
||||
jpanel.add(jlabel, BorderLayout.WEST);
|
||||
jpanel.add(jlabel1, BorderLayout.CENTER);
|
||||
jpanel.add(label1, BorderLayout.CENTER);
|
||||
jpanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
|
||||
add(jpanel, BorderLayout.NORTH);
|
||||
myBrowser = TipUIUtil.createTipBrowser();
|
||||
@@ -63,7 +64,8 @@ public class TipPanel extends JPanel {
|
||||
final GeneralSettings settings = GeneralSettings.getInstance();
|
||||
showOnStartCheckBox.setSelected(settings.isShowTipsOnStartup());
|
||||
showOnStartCheckBox.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
@Override
|
||||
public void itemStateChanged(@NotNull ItemEvent e) {
|
||||
settings.setShowTipsOnStartup(e.getStateChange() == ItemEvent.SELECTED);
|
||||
}
|
||||
});
|
||||
@@ -79,6 +81,7 @@ public class TipPanel extends JPanel {
|
||||
Collections.addAll(myTips, Extensions.getExtensions(TipAndTrickBean.EP_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
}
|
||||
|
||||
@@ -771,15 +771,16 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
|
||||
try {
|
||||
final FileEditorProvider provider = newProviders[i];
|
||||
LOG.assertTrue(provider != null, "Provider for file "+file+" is null. All providers: "+Arrays.asList(newProviders));
|
||||
LOG.assertTrue(provider.accept(myProject, file), "Provider " + provider + " doesn't accept file " + file);
|
||||
if ((provider instanceof AsyncFileEditorProvider)) {
|
||||
builders[i] = ApplicationManager.getApplication().runReadAction(new Computable<AsyncFileEditorProvider.Builder>() {
|
||||
@Override
|
||||
public AsyncFileEditorProvider.Builder compute() {
|
||||
return ((AsyncFileEditorProvider)provider).createEditorAsync(myProject, file);
|
||||
builders[i] = ApplicationManager.getApplication().runReadAction(new Computable<AsyncFileEditorProvider.Builder>() {
|
||||
@Override
|
||||
public AsyncFileEditorProvider.Builder compute() {
|
||||
if (myProject.isDisposed() || !file.isValid()) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
LOG.assertTrue(provider.accept(myProject, file), "Provider " + provider + " doesn't accept file " + file);
|
||||
return provider instanceof AsyncFileEditorProvider ? ((AsyncFileEditorProvider)provider).createEditorAsync(myProject, file) : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.options.ConfigurableGroup;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.LightColors;
|
||||
import com.intellij.ui.SearchTextField;
|
||||
@@ -58,6 +59,11 @@ abstract class SettingsFilter extends ElementFilter.Active.Impl<SimpleNode> {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent event) {
|
||||
update(event.getType(), true, false);
|
||||
// request focus if needed on changing the filter text
|
||||
IdeFocusManager manager = IdeFocusManager.findInstanceByComponent(mySearch);
|
||||
if (manager.getFocusedDescendantFor(mySearch) == null) {
|
||||
manager.requestFocus(mySearch, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
mySearch.getTextEditor().addMouseListener(new MouseAdapter() {
|
||||
|
||||
@@ -46,6 +46,7 @@ import com.intellij.ui.*;
|
||||
import com.intellij.ui.border.CustomLineBorder;
|
||||
import com.intellij.ui.components.labels.ActionLink;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -59,7 +60,6 @@ import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -92,6 +92,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
} else {
|
||||
setSize(555, 460);
|
||||
}
|
||||
setResizable(false);
|
||||
//int x = bounds.x + (bounds.width - getWidth()) / 2;
|
||||
//int y = bounds.y + (bounds.height - getHeight()) / 2;
|
||||
Point location = DimensionService.getInstance().getLocation(WelcomeFrame.DIMENSION_KEY, null);
|
||||
@@ -166,13 +167,29 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
}
|
||||
|
||||
public static Color getMainBackground() {
|
||||
return new JBColor(new Color(0xf5f6f8), new Color(0x3c3f41));
|
||||
return new JBColor(0xf7f7f7, 0x45474a);
|
||||
}
|
||||
|
||||
public static Color getProjectsBackGround() {
|
||||
return new JBColor(Gray.xFF, new Color(58, 61, 63));
|
||||
public static Color getProjectsBackground() {
|
||||
return new JBColor(Gray.xFF, Gray.x39);
|
||||
}
|
||||
|
||||
public static Color getLinkNormalColor() {
|
||||
return new JBColor(Gray._0, Gray.xBB);
|
||||
}
|
||||
|
||||
public static Color getListSelectionColor(boolean hasFocus) {
|
||||
return hasFocus ? new JBColor(0x3875d6, 0x4b6eaf) : new JBColor(Gray.xDD, Gray.x45);
|
||||
}
|
||||
|
||||
public static Color getActionLinkSelectionColor() {
|
||||
return new JBColor(0xdbe5f5, 0x485875);
|
||||
}
|
||||
|
||||
public static JBColor getSeparatorColor() {
|
||||
return new JBColor(Gray.xEC, new Color(72, 75, 78));
|
||||
}
|
||||
|
||||
private class FlatWelcomeScreen extends JPanel implements WelcomeScreen {
|
||||
public FlatWelcomeScreen() {
|
||||
super(new BorderLayout());
|
||||
@@ -193,7 +210,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
}
|
||||
|
||||
private void removeIfNeeded() {
|
||||
if (projectsList.getModel().getSize() == 0) {
|
||||
if (RecentProjectsManager.getInstance().getRecentProjectsActions(false).length == 0) {
|
||||
FlatWelcomeScreen.this.remove(recentProjects);
|
||||
FlatWelcomeScreen.this.revalidate();
|
||||
FlatWelcomeScreen.this.repaint();
|
||||
@@ -205,6 +222,17 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
removeIfNeeded();
|
||||
}
|
||||
});
|
||||
projectsList.addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
projectsList.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
projectsList.repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
add(createBody(), BorderLayout.CENTER);
|
||||
@@ -224,17 +252,41 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
}
|
||||
|
||||
private JComponent createSettingsAndDocs() {
|
||||
NonOpaquePanel toolbar = new NonOpaquePanel();
|
||||
toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
|
||||
toolbar.add(createActionLink("Configure", IdeActions.GROUP_WELCOME_SCREEN_CONFIGURE, AllIcons.General.Settings));
|
||||
toolbar.add(createActionLink("Get Help", IdeActions.GROUP_WELCOME_SCREEN_DOC, null));
|
||||
JPanel panel = new NonOpaquePanel(new BorderLayout());
|
||||
NonOpaquePanel toolbar = new NonOpaquePanel();
|
||||
AnAction register = ActionManager.getInstance().getAction("Register");
|
||||
boolean registeredVisible = false;
|
||||
if (register != null) {
|
||||
Presentation presentation = register.getTemplatePresentation();
|
||||
register.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(this),
|
||||
ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0));
|
||||
if (presentation.isEnabled()) {
|
||||
ActionLink registerLink = new ActionLink("Register", register);
|
||||
registerLink.setNormalColor(getLinkNormalColor());
|
||||
NonOpaquePanel button = new NonOpaquePanel(new BorderLayout());
|
||||
button.setBorder(new EmptyBorder(4, 10, 4, 10));
|
||||
button.add(registerLink);
|
||||
installFocusable(button, register, KeyEvent.VK_UP, KeyEvent.VK_RIGHT, true);
|
||||
NonOpaquePanel wrap = new NonOpaquePanel();
|
||||
wrap.setBorder(new EmptyBorder(0, 10, 0, 0));
|
||||
wrap.add(button);
|
||||
panel.add(wrap, BorderLayout.WEST);
|
||||
registeredVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
|
||||
toolbar.add(createActionLink("Configure", IdeActions.GROUP_WELCOME_SCREEN_CONFIGURE, AllIcons.General.Settings, !registeredVisible));
|
||||
toolbar.add(createActionLink("Get Help", IdeActions.GROUP_WELCOME_SCREEN_DOC, null, false));
|
||||
|
||||
panel.add(toolbar, BorderLayout.EAST);
|
||||
|
||||
|
||||
panel.setBorder(new EmptyBorder(0,0,8,21));
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JComponent createActionLink(final String text, final String groupId, Icon icon) {
|
||||
private JComponent createActionLink(final String text, final String groupId, Icon icon, boolean focusListOnLeft) {
|
||||
final Ref<ActionLink> settings = new Ref<ActionLink>(null);
|
||||
AnAction action = new AnAction() {
|
||||
@Override
|
||||
@@ -248,11 +300,12 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
};
|
||||
settings.set(new ActionLink(text, icon, action));
|
||||
settings.get().setPaintUnderline(false);
|
||||
settings.get().setNormalColor(getLinkNormalColor());
|
||||
NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout());
|
||||
panel.setBorder(new EmptyBorder(4, 16, 4, 4));
|
||||
panel.setBorder(new EmptyBorder(4, 10, 4, 10));
|
||||
panel.add(settings.get());
|
||||
panel.add(new JLabel(AllIcons.General.Combo2), BorderLayout.EAST);
|
||||
installFocusable(panel, action, KeyEvent.VK_UP, KeyEvent.VK_DOWN, !Arrays.asList("Get Help", "Register").contains(text));
|
||||
panel.add(createArrow(settings.get()), BorderLayout.EAST);
|
||||
installFocusable(panel, action, KeyEvent.VK_UP, KeyEvent.VK_DOWN, focusListOnLeft);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -264,12 +317,6 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
collectAllActions(group, quickStart);
|
||||
|
||||
// so, we sure this is the last action
|
||||
final AnAction register = actionManager.getAction("WelcomeScreen.Register");
|
||||
if (register != null) {
|
||||
group.add(register);
|
||||
}
|
||||
|
||||
for (AnAction action : group.getChildren(null)) {
|
||||
JPanel button = new JPanel(new BorderLayout());
|
||||
button.setOpaque(false);
|
||||
@@ -278,11 +325,22 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
action.update(new AnActionEvent(null, DataManager.getInstance().getDataContext(this),
|
||||
ActionPlaces.WELCOME_SCREEN, presentation, ActionManager.getInstance(), 0));
|
||||
if (presentation.isVisible()) {
|
||||
ActionLink link = new ActionLink(presentation.getText(), presentation.getIcon(), action);
|
||||
String text = presentation.getText();
|
||||
if (text.endsWith("...")) {
|
||||
text = text.substring(0, text.length() - 3);
|
||||
}
|
||||
Icon icon = presentation.getIcon();
|
||||
if (icon.getIconHeight() != 16 || icon.getIconWidth() != 16) {
|
||||
icon = EmptyIcon.ICON_16;
|
||||
}
|
||||
ActionLink link = new ActionLink(text, icon, action);
|
||||
link.setPaintUnderline(false);
|
||||
link.setNormalColor(new JBColor(Gray._0, Gray.xBB));
|
||||
installFocusable(button, action, KeyEvent.VK_UP, KeyEvent.VK_DOWN, true);
|
||||
link.setNormalColor(getLinkNormalColor());
|
||||
button.add(link);
|
||||
if (action instanceof WelcomePopupAction) {
|
||||
button.add(createArrow(link), BorderLayout.EAST);
|
||||
}
|
||||
installFocusable(button, action, KeyEvent.VK_UP, KeyEvent.VK_DOWN, true);
|
||||
actions.add(button);
|
||||
}
|
||||
}
|
||||
@@ -306,7 +364,6 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
private JComponent createLogo() {
|
||||
NonOpaquePanel panel = new NonOpaquePanel(new BorderLayout());
|
||||
JLabel logo = new JLabel(IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getWelcomeScreenLogoUrl()));
|
||||
logo.setBorder(new EmptyBorder(20, 0, 0, 0));
|
||||
logo.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
panel.add(logo, BorderLayout.NORTH);
|
||||
JLabel appName = new JLabel(ApplicationNamesInfo.getInstance().getFullProductName());
|
||||
@@ -321,6 +378,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
|
||||
panel.add(appName);
|
||||
panel.add(version, BorderLayout.SOUTH);
|
||||
panel.setBorder(new EmptyBorder(20, 10, 30, 10));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -350,8 +408,8 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
private JComponent createRecentProjects() {
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(new NewRecentProjectPanel(this), BorderLayout.CENTER);
|
||||
panel.setBackground(getProjectsBackGround());
|
||||
panel.setBorder(new CustomLineBorder(new JBColor(Gray.xEC, new Color(0x3c3f41)), 0,0,0,1));
|
||||
panel.setBackground(getProjectsBackground());
|
||||
panel.setBorder(new CustomLineBorder(getSeparatorColor(), 0,0,0,1));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -390,7 +448,7 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
comp.setOpaque(true);
|
||||
comp.setBackground(new JBColor(new Color(0xd2e1f0), new Color(0x455565)));
|
||||
comp.setBackground(getActionLinkSelectionColor());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -479,6 +537,22 @@ public class FlatWelcomeFrame extends JFrame implements IdeFrame {
|
||||
}
|
||||
}
|
||||
|
||||
private static JLabel createArrow(final ActionLink link) {
|
||||
JLabel arrow = new JLabel(AllIcons.General.Combo3);
|
||||
arrow.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
arrow.setVerticalAlignment(SwingConstants.BOTTOM);
|
||||
new ClickListener() {
|
||||
@Override
|
||||
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
|
||||
final MouseEvent newEvent = new MouseEvent(link, e.getID(), e.getWhen(), e.getModifiers(), e.getX(), e.getY(), e.getClickCount(),
|
||||
e.isPopupTrigger(), e.getButton());
|
||||
link.doClick(newEvent);
|
||||
return true;
|
||||
}
|
||||
}.installOn(arrow);
|
||||
return arrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BalloonLayout getBalloonLayout() {
|
||||
return myBalloonLayout;
|
||||
|
||||
@@ -37,17 +37,17 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
|
||||
public NewRecentProjectPanel(WelcomeScreen screen) {
|
||||
super(screen);
|
||||
setBorder(null);
|
||||
setBackground(FlatWelcomeFrame.getProjectsBackGround());
|
||||
setBackground(FlatWelcomeFrame.getProjectsBackground());
|
||||
JScrollPane scrollPane = UIUtil.findComponentOfType(this, JScrollPane.class);
|
||||
if (scrollPane != null) {
|
||||
scrollPane.setBackground(FlatWelcomeFrame.getProjectsBackGround());
|
||||
scrollPane.setBackground(FlatWelcomeFrame.getProjectsBackground());
|
||||
scrollPane.setSize(245, 460);
|
||||
scrollPane.setMinimumSize(new Dimension(245, 460));
|
||||
scrollPane.setPreferredSize(new Dimension(245, 460));
|
||||
}
|
||||
ListWithFilter panel = UIUtil.findComponentOfType(this, ListWithFilter.class);
|
||||
if (panel != null) {
|
||||
panel.setBackground(FlatWelcomeFrame.getProjectsBackGround());
|
||||
panel.setBackground(FlatWelcomeFrame.getProjectsBackground());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
|
||||
@Override
|
||||
protected JBList createList(AnAction[] recentProjectActions, Dimension size) {
|
||||
final JBList list = super.createList(recentProjectActions, size);
|
||||
list.setBackground(FlatWelcomeFrame.getProjectsBackGround());
|
||||
list.setBackground(FlatWelcomeFrame.getProjectsBackground());
|
||||
list.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
@@ -87,12 +87,12 @@ public class NewRecentProjectPanel extends RecentProjectPanel {
|
||||
}
|
||||
@Override
|
||||
protected Color getListBackground(boolean isSelected, boolean hasFocus) {
|
||||
return isSelected ? new Color(0x2484fd) : FlatWelcomeFrame.getProjectsBackGround();
|
||||
return isSelected ? FlatWelcomeFrame.getListSelectionColor(hasFocus) : FlatWelcomeFrame.getProjectsBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getListForeground(boolean isSelected, boolean hasFocus) {
|
||||
return UIUtil.getListForeground(isSelected);
|
||||
return UIUtil.getListForeground(isSelected && hasFocus);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -257,8 +257,8 @@ public class RecentProjectPanel extends JPanel {
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
ReopenProjectAction item = (ReopenProjectAction)value;
|
||||
|
||||
Color fore = getListForeground(isSelected, cellHasFocus);
|
||||
Color back = getListBackground(isSelected, cellHasFocus);
|
||||
Color fore = getListForeground(isSelected, list.hasFocus());
|
||||
Color back = getListBackground(isSelected, list.hasFocus());
|
||||
|
||||
myName.setForeground(fore);
|
||||
myPath.setForeground(isSelected ? fore : UIUtil.getInactiveTextColor());
|
||||
|
||||
@@ -57,6 +57,7 @@ import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
@@ -792,6 +793,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
|
||||
private void hideAndDispose(final boolean ok) {
|
||||
if (myDisposed) return;
|
||||
myDisposed = true;
|
||||
hideComboBoxPopups();
|
||||
|
||||
final Runnable disposeRunnable = new Runnable() {
|
||||
@Override
|
||||
@@ -827,6 +829,13 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
|
||||
myTracker = null;
|
||||
}
|
||||
|
||||
private void hideComboBoxPopups() {
|
||||
List<JComboBox> comboBoxes = UIUtil.findComponentsOfType(myComp, JComboBox.class);
|
||||
for (JComboBox box : comboBoxes) {
|
||||
box.hidePopup();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onDisposed() { }
|
||||
|
||||
@Override
|
||||
|
||||
@@ -747,7 +747,7 @@ public class AbstractPopup implements JBPopup {
|
||||
|
||||
Point xy = new Point(aScreenX, aScreenY);
|
||||
boolean adjustXY = true;
|
||||
if (myDimensionServiceKey != null) {
|
||||
if (myUseDimServiceForXYLocation && myDimensionServiceKey != null) {
|
||||
final Point storedLocation = DimensionService.getInstance().getLocation(myDimensionServiceKey, myProject);
|
||||
if (storedLocation != null) {
|
||||
xy = storedLocation;
|
||||
|
||||
@@ -436,13 +436,10 @@ public class SwingHelper {
|
||||
textPane.setContentType(UIUtil.HTML_MIME);
|
||||
textPane.setEditable(false);
|
||||
if (background != null) {
|
||||
textPane.setBackground(background); // e.g. UIUtil.getOptionPaneBackground()
|
||||
textPane.setBackground(background);
|
||||
}
|
||||
else {
|
||||
textPane.setOpaque(false);
|
||||
if (UIUtil.isUnderNimbusLookAndFeel()) {
|
||||
textPane.setBackground(UIUtil.TRANSPARENT_COLOR);
|
||||
}
|
||||
}
|
||||
textPane.setForeground(foreground != null ? foreground : UIUtil.getLabelForeground());
|
||||
return textPane;
|
||||
|
||||
@@ -1009,8 +1009,8 @@ action.ChangeKeymap.text=Keymap
|
||||
action.ChangeKeymap.description=Change current keymap
|
||||
action.ChangeLaf.text=Look and Feel
|
||||
action.ChangeLaf.description=Change current Look\\&Feel
|
||||
action.ChangeView.text=Screen Mode
|
||||
action.ChangeView.description=Change screen mode
|
||||
action.ChangeView.text=View Mode
|
||||
action.ChangeView.description=Change view mode
|
||||
action.ChangeInspectionProfile.text=Switch Error Highlighting
|
||||
action.ChangeInspectionProfile.description=Change current editor inspection profile
|
||||
action.ChangeCustomizationSchema.text=Switch Customization Scheme
|
||||
|
||||
@@ -303,3 +303,7 @@ exportable.NotificationConfiguration.presentable.name=Notifications
|
||||
exportable.CodeInsightSettings.presentable.name=CodeInsight
|
||||
exportable.HttpConfigurable.presentable.name=HTTP Proxy
|
||||
exportable.KeymapManager.presentable.name=Key maps
|
||||
exportable.UsageViewSettings.presentable.name=Usage View
|
||||
exportable.BaseRefactoringSettings.presentable.name=Refactoring
|
||||
exportable.DuplocatorSettings.presentable.name=Duplocator
|
||||
exportable.MultiLanguageDuplocatorSettings.presentable.name=Duplocator
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.jetbrains.rpc;
|
||||
import com.intellij.util.text.StringFactory;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
@@ -29,7 +31,7 @@ public final class ChannelBufferToString {
|
||||
}
|
||||
}
|
||||
|
||||
public static CharBuffer readIntoCharBuffer(CharBuffer charBuffer, ByteBuf buffer, int byteCount) {
|
||||
public static CharBuffer readIntoCharBuffer(@Nullable CharBuffer charBuffer, @NotNull ByteBuf buffer, int byteCount) {
|
||||
CharsetDecoder decoder = CharsetUtil.getDecoder(CharsetUtil.UTF_8);
|
||||
ByteBuffer in = buffer.nioBuffer(buffer.readerIndex(), byteCount);
|
||||
if (charBuffer == null) {
|
||||
@@ -52,4 +54,11 @@ public final class ChannelBufferToString {
|
||||
buffer.skipBytes(byteCount);
|
||||
return charBuffer;
|
||||
}
|
||||
|
||||
public static void writeIntAsAscii(int value, @NotNull ByteBuf buffer) {
|
||||
String string = Integer.toString(value);
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
buffer.writeByte(string.charAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package org.jetbrains.rpc;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.io.SimpleChannelInboundHandlerAdapter;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
public abstract class MessageDecoder extends SimpleChannelInboundHandlerAdapter<ByteBuf> {
|
||||
protected int contentLength;
|
||||
protected final StringBuilder builder = new StringBuilder(64);
|
||||
|
||||
private CharBuffer chunkedContent;
|
||||
private int consumedContentByteCount = 0;
|
||||
|
||||
protected final int parseContentLength() {
|
||||
return parseInt(builder, 0, false, 10);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String doReadContent(@NotNull ByteBuf buffer) {
|
||||
int required = contentLength - consumedContentByteCount;
|
||||
String result;
|
||||
if (buffer.readableBytes() < required) {
|
||||
if (chunkedContent == null) {
|
||||
chunkedContent = CharBuffer.allocate(contentLength);
|
||||
}
|
||||
|
||||
int count = buffer.readableBytes();
|
||||
ChannelBufferToString.readIntoCharBuffer(chunkedContent, buffer, count);
|
||||
consumedContentByteCount += count;
|
||||
return null;
|
||||
}
|
||||
else if (chunkedContent != null) {
|
||||
ChannelBufferToString.readIntoCharBuffer(chunkedContent, buffer, required);
|
||||
result = ChannelBufferToString.charBufferToString(chunkedContent);
|
||||
|
||||
chunkedContent = null;
|
||||
consumedContentByteCount = 0;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
// we can produce char sequence CharSequence result = CharsetUtil.UTF_8.decode(buffer.toByteBuffer(buffer.readerIndex(), required));
|
||||
// but later, in JsonReaderEx, it will be toString in any case, so, in this case, intermediate java.nio.HeapCharBuffer will be created - so, we stay with String
|
||||
return ChannelBufferToString.readString(buffer, required);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
|
||||
* Copyright (C) 2006 - Javolution (http://javolution.org/)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software is
|
||||
* freely granted, provided that this notice is preserved.
|
||||
*/
|
||||
private static int parseInt(final CharSequence value, final int start, final boolean isNegative, final int radix) {
|
||||
final int end = value.length();
|
||||
int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
|
||||
int i = start;
|
||||
for (; i < end; i++) {
|
||||
char c = value.charAt(i);
|
||||
int digit = (c <= '9') ? c - '0'
|
||||
: ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
|
||||
: ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
|
||||
if ((digit >= 0) && (digit < radix)) {
|
||||
int newResult = result * radix - digit;
|
||||
if (newResult > result) {
|
||||
throw new NumberFormatException("Overflow parsing " + value.subSequence(start, end));
|
||||
}
|
||||
result = newResult;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Requires one valid digit character and checks for opposite overflow.
|
||||
if ((result == 0) && ((end == 0) || (value.charAt(i - 1) != '0'))) {
|
||||
throw new NumberFormatException("Invalid integer representation for " + value.subSequence(start, end));
|
||||
}
|
||||
if ((result == Integer.MIN_VALUE) && !isNegative) {
|
||||
throw new NumberFormatException("Overflow parsing " + value.subSequence(start, end));
|
||||
}
|
||||
return isNegative ? result : -result;
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,22 @@ package org.jetbrains.debugger.connection;
|
||||
|
||||
import com.intellij.ide.browsers.WebBrowser;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.socketConnection.ConnectionStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.debugger.Vm;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -87,4 +94,46 @@ public abstract class RemoteVmConnection extends VmConnection<Vm> {
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> AsyncResult<T> chooseDebuggee(@NotNull final Collection<T> targets, final int selectedIndex, @NotNull final Function<T, String> itemToString) {
|
||||
if (targets.size() == 1) {
|
||||
return AsyncResult.done(ContainerUtil.getFirstItem(targets));
|
||||
}
|
||||
|
||||
final AsyncResult<T> result = new AsyncResult<T>();
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final JBList list = new JBList(targets);
|
||||
list.setCellRenderer(new ColoredListCellRenderer() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
//noinspection unchecked
|
||||
append(itemToString.fun((T)value));
|
||||
}
|
||||
});
|
||||
list.setSelectedIndex(selectedIndex);
|
||||
|
||||
JBPopupFactory.getInstance().
|
||||
createListPopupBuilder(list).
|
||||
setTitle("Choose Page to debug").
|
||||
setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@SuppressWarnings("unchecked")
|
||||
T value = (T)list.getSelectedValue();
|
||||
if (value == null) {
|
||||
result.setRejected();
|
||||
}
|
||||
else {
|
||||
result.setDone(value);
|
||||
}
|
||||
}
|
||||
}).
|
||||
createPopup().showInFocusCenter();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ public abstract class VmConnection<T extends Vm> implements Disposable, BrowserC
|
||||
protected volatile T vm;
|
||||
|
||||
private final ActionCallback opened = new ActionCallback();
|
||||
|
||||
private final AtomicBoolean closed = new AtomicBoolean();
|
||||
|
||||
public final Vm getVm() {
|
||||
|
||||
@@ -665,6 +665,15 @@ public final class JsonReaderEx implements Closeable {
|
||||
* Returns the next token, a {@link JsonToken#NAME property name}, and consumes it
|
||||
*/
|
||||
public String nextName() {
|
||||
String result = nextNameOrNull();
|
||||
if (result == null) {
|
||||
throw createParseError("Expected a name but was " + peek());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String nextNameOrNull() {
|
||||
int p = peeked;
|
||||
if (p == PEEKED_NONE) {
|
||||
p = doPeek();
|
||||
@@ -680,7 +689,10 @@ public final class JsonReaderEx implements Closeable {
|
||||
result = nextQuotedValue('"');
|
||||
}
|
||||
else {
|
||||
throw createParseError("Expected a name but was " + peek());
|
||||
if (p != PEEKED_END_OBJECT && p != PEEKED_END_ARRAY) {
|
||||
throw createParseError("Expected a name but was " + peek());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
peeked = PEEKED_NONE;
|
||||
return result;
|
||||
@@ -713,6 +725,7 @@ public final class JsonReaderEx implements Closeable {
|
||||
return in.charAt(offset + index);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
if ((end - start) > length) {
|
||||
@@ -1153,6 +1166,7 @@ public final class JsonReaderEx implements Closeable {
|
||||
/**
|
||||
* Closes this JSON reader and the underlying {@link java.io.Reader}.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
peeked = PEEKED_NONE;
|
||||
stack[0] = JsonScope.CLOSED;
|
||||
@@ -1180,11 +1194,7 @@ public final class JsonReaderEx implements Closeable {
|
||||
push(JsonScope.EMPTY_OBJECT);
|
||||
count++;
|
||||
}
|
||||
else if (p == PEEKED_END_ARRAY) {
|
||||
stackSize--;
|
||||
count--;
|
||||
}
|
||||
else if (p == PEEKED_END_OBJECT) {
|
||||
else if (p == PEEKED_END_ARRAY || p == PEEKED_END_OBJECT) {
|
||||
stackSize--;
|
||||
count--;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.jetbrains.jsonProtocol;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
@@ -10,6 +10,6 @@
|
||||
<orderEntry type="library" name="Trove4j" level="project" />
|
||||
<orderEntry type="library" name="gson" level="project" />
|
||||
<orderEntry type="module" module-name="protocol-reader-runtime" exported="" />
|
||||
<orderEntry type="module" module-name="annotations" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -1,29 +0,0 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
class AbsentSubtypeAspect extends SubtypeAspect {
|
||||
|
||||
@Override
|
||||
void writeGetSuperMethodJava(TextOutput out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperFieldJava(TextOutput out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperConstructorParamJava(TextOutput out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperConstructorInitialization(TextOutput out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeParseMethod(String className, ClassScope scope, TextOutput out) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInstantiateCode(String className, TextOutput out) {
|
||||
out.append("new ").append(className);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import java.util.*;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DynamicReader<ROOT> {
|
||||
final LinkedHashMap<Class<?>, TypeHandler<?>> typeToTypeHandler;
|
||||
@@ -15,20 +16,20 @@ public class DynamicReader<ROOT> {
|
||||
root = new ReaderRoot<>(readerRootClass, typeToTypeHandler);
|
||||
}
|
||||
|
||||
public GeneratedCodeMap generateStaticReader(StringBuilder stringBuilder, String packageName, String className,
|
||||
Collection<GeneratedCodeMap> basePackages) {
|
||||
final GlobalScope globalScope = new GlobalScope(typeToTypeHandler.values(), basePackages);
|
||||
@NotNull
|
||||
public GeneratedCodeMap generateReader(StringBuilder stringBuilder, String packageName, String className,
|
||||
Collection<GeneratedCodeMap> basePackages) {
|
||||
GlobalScope globalScope = new GlobalScope(typeToTypeHandler.values(), basePackages);
|
||||
FileScope fileScope = globalScope.newFileScope(stringBuilder);
|
||||
final TextOutput out = fileScope.getOutput();
|
||||
TextOutput out = fileScope.getOutput();
|
||||
out.append("// Generated source");
|
||||
out.newLine().append("package ").append(packageName).append(';');
|
||||
out.newLine().newLine().append("import org.jetbrains.jsonProtocol.*;");
|
||||
out.newLine().newLine().append("import static org.jetbrains.jsonProtocol.JsonReaders.*;");
|
||||
out.newLine().newLine().append("public final class ").append(className).space();
|
||||
out.append(root.getType().isInterface() ? "implements" : "extends").space().append(root.getType().getCanonicalName()).openBlock(
|
||||
false);
|
||||
out.append(root.getType().isInterface() ? "implements" : "extends").space().append(root.getType().getCanonicalName()).openBlock(false);
|
||||
|
||||
final ClassScope rootClassScope = fileScope.newClassScope();
|
||||
ClassScope rootClassScope = fileScope.newClassScope();
|
||||
root.writeStaticMethodJava(rootClassScope);
|
||||
|
||||
for (TypeHandler<?> typeHandler : typeToTypeHandler.values()) {
|
||||
@@ -37,27 +38,31 @@ public class DynamicReader<ROOT> {
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
boolean isFirst = true;
|
||||
for (TypeHandler<?> typeHandler : globalScope.getTypeFactories()) {
|
||||
String name = globalScope.getTypeImplShortName(typeHandler);
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
}
|
||||
else {
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
String originName = typeHandler.getTypeClass().getCanonicalName();
|
||||
out.newLine().append("static final class ").append(name).append(Util.TYPE_FACTORY_NAME_POSTFIX).append(" extends ObjectFactory<");
|
||||
out.newLine().append("private static final class ").append(globalScope.getTypeImplShortName(typeHandler)).append(Util.TYPE_FACTORY_NAME_POSTFIX).append(" extends ObjectFactory<");
|
||||
out.append(originName).append('>').openBlock();
|
||||
out.append("@Override").newLine().append("public ").append(originName).append(" read(").append(Util.JSON_READER_PARAMETER_DEF);
|
||||
out.append(')').openBlock();
|
||||
out.append("return ");
|
||||
typeHandler.writeInstantiateCode(rootClassScope, out);
|
||||
out.append('(').append(Util.READER_NAME).append(");").closeBlock();
|
||||
out.append('(').append(Util.READER_NAME).append(", null);").closeBlock();
|
||||
out.closeBlock();
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
out.closeBlock();
|
||||
|
||||
Map<Class<?>, String> typeToImplClassName = new HashMap<>();
|
||||
Map<Class<?>, String> typeToImplClassName = new THashMap<>();
|
||||
for (TypeHandler<?> typeHandler : typeToTypeHandler.values()) {
|
||||
String shortName = fileScope.getTypeImplShortName(typeHandler);
|
||||
String fullReference = packageName + "." + className + "." + shortName;
|
||||
typeToImplClassName.put(typeHandler.getTypeClass(), fullReference);
|
||||
typeToImplClassName.put(typeHandler.getTypeClass(), packageName + "." + className + "." + fileScope.getTypeImplShortName(typeHandler));
|
||||
}
|
||||
|
||||
return new GeneratedCodeMap(typeToImplClassName);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
class ExistingSubtypeAspect extends SubtypeAspect {
|
||||
class ExistingSubtypeAspect {
|
||||
private SubtypeCaster subtypeCaster;
|
||||
private final TypeRef<?> jsonSuperClass;
|
||||
|
||||
@@ -12,28 +12,23 @@ class ExistingSubtypeAspect extends SubtypeAspect {
|
||||
this.subtypeCaster = subtypeCaster;
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeGetSuperMethodJava(TextOutput out) {
|
||||
out.newLine().append("@Override").newLine().append("public ").append(jsonSuperClass.get().getTypeClass().getCanonicalName() ).append(" getSuper()").openBlock();
|
||||
out.append("return ").append(Util.BASE_VALUE_PREFIX).semi().closeBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperFieldJava(TextOutput out) {
|
||||
out.newLine().append("private final ").append(jsonSuperClass.get().getTypeClass().getCanonicalName()).append(' ').append(Util.BASE_VALUE_PREFIX).semi().newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperConstructorParamJava(TextOutput out) {
|
||||
out.comma().append(jsonSuperClass.get().getTypeClass().getCanonicalName()).append(' ').append(Util.BASE_VALUE_PREFIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeSuperConstructorInitialization(TextOutput out) {
|
||||
out.append("this.").append(Util.BASE_VALUE_PREFIX).append(" = ").append(Util.BASE_VALUE_PREFIX).append(';').newLine().newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeParseMethod(String className, ClassScope scope, TextOutput out) {
|
||||
out.newLine().append("public static ").append(className).space().append("parse").append("(").append(Util.JSON_READER_PARAMETER_DEF).append(')').openBlock();
|
||||
out.append("return ");
|
||||
@@ -44,7 +39,6 @@ class ExistingSubtypeAspect extends SubtypeAspect {
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInstantiateCode(String className, TextOutput out) {
|
||||
out.append(className).append(".parse");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jsonProtocol.JsonField;
|
||||
import org.jetbrains.jsonProtocol.JsonNullable;
|
||||
import org.jetbrains.jsonProtocol.JsonOptionalField;
|
||||
@@ -28,7 +29,7 @@ class FieldProcessor<T> {
|
||||
// todo sort by source location
|
||||
Arrays.sort(methods, new Comparator<Method>() {
|
||||
@Override
|
||||
public int compare(Method o1, Method o2) {
|
||||
public int compare(@NotNull Method o1, @NotNull Method o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
@@ -120,20 +121,10 @@ class FieldProcessor<T> {
|
||||
int position = volatileFields.size();
|
||||
FieldTypeInfo fieldTypeInfo;
|
||||
if (internalType) {
|
||||
fieldTypeInfo = new FieldTypeInfo() {
|
||||
@Override
|
||||
public void appendValueTypeNameJava(FileScope scope, TextOutput out) {
|
||||
fieldTypeParser.appendInternalValueTypeName(scope, out);
|
||||
}
|
||||
};
|
||||
fieldTypeInfo = fieldTypeParser::appendInternalValueTypeName;
|
||||
}
|
||||
else {
|
||||
fieldTypeInfo = new FieldTypeInfo() {
|
||||
@Override
|
||||
public void appendValueTypeNameJava(FileScope scope, TextOutput out) {
|
||||
fieldTypeParser.appendFinishedValueTypeName(out);
|
||||
}
|
||||
};
|
||||
fieldTypeInfo = (scope, out) -> fieldTypeParser.appendFinishedValueTypeName(out);
|
||||
}
|
||||
VolatileFieldBinding binding = new VolatileFieldBinding(position, fieldTypeInfo);
|
||||
volatileFields.add(binding);
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.protocolReader;
|
||||
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -84,7 +85,7 @@ public class GlobalScope {
|
||||
// Sort to produce consistent GeneratedCodeMap later.
|
||||
Collections.sort(list, new Comparator<TypeHandler<?>>() {
|
||||
@Override
|
||||
public int compare(TypeHandler<?> o1, TypeHandler<?> o2) {
|
||||
public int compare(@NotNull TypeHandler<?> o1, @NotNull TypeHandler<?> o2) {
|
||||
return getName(o1).compareTo(getName(o2));
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,10 @@ class InterfaceReader {
|
||||
}
|
||||
|
||||
for (SubtypeCaster subtypeCaster : subtypeCasters) {
|
||||
subtypeCaster.getSubtypeHandler().getSubtypeSupport().setSubtypeCaster(subtypeCaster);
|
||||
ExistingSubtypeAspect subtypeSupport = subtypeCaster.getSubtypeHandler().getSubtypeSupport();
|
||||
if (subtypeSupport != null) {
|
||||
subtypeSupport.setSubtypeCaster(subtypeCaster);
|
||||
}
|
||||
}
|
||||
|
||||
return typeToTypeHandler;
|
||||
|
||||
@@ -4,19 +4,22 @@
|
||||
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
abstract class MethodHandler {
|
||||
abstract void writeMethodImplementationJava(ClassScope classScope, Method m, TextOutput out);
|
||||
|
||||
protected static void appendMethodSignatureJava(Method m, Iterable<String> paramNames, TextOutput out) {
|
||||
protected static void appendMethodSignatureJava(@NotNull Method m, @NotNull List<String> paramNames, @NotNull TextOutput out) {
|
||||
out.append(m.getName()).append('(');
|
||||
boolean firstArg = true;
|
||||
Iterator<String> namesIt = paramNames.iterator();
|
||||
for (Type arg : m.getGenericParameterTypes()) {
|
||||
Type[] types = m.getGenericParameterTypes();
|
||||
for (int i = 0, length = types.length; i < length; i++) {
|
||||
Type arg = types[i];
|
||||
if (firstArg) {
|
||||
firstArg = false;
|
||||
}
|
||||
@@ -24,7 +27,7 @@ abstract class MethodHandler {
|
||||
out.comma();
|
||||
}
|
||||
Util.writeJavaTypeName(arg, out);
|
||||
out.append(' ').append(namesIt.next());
|
||||
out.space().append(paramNames.get(i));
|
||||
}
|
||||
out.append(')');
|
||||
}
|
||||
@@ -33,10 +36,10 @@ abstract class MethodHandler {
|
||||
writeMethodDeclarationJava(out, m, Collections.<String>emptyList());
|
||||
}
|
||||
|
||||
protected static void writeMethodDeclarationJava(TextOutput out, Method m, Iterable<String> paramNames) {
|
||||
protected static void writeMethodDeclarationJava(@NotNull TextOutput out, @NotNull Method m, @NotNull List<String> paramNames) {
|
||||
out.append("@Override").newLine().append("public ");
|
||||
Util.writeJavaTypeName(m.getGenericReturnType(), out);
|
||||
out.append(' ');
|
||||
out.space();
|
||||
appendMethodSignatureJava(m, paramNames, out);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ObjectValueReader<T> extends ValueReader {
|
||||
refToType.get().writeInstantiateCode(scope.getRootClassScope(), subtyping, out);
|
||||
out.append('(');
|
||||
addReaderParameter(subtyping, out);
|
||||
if (subtyping && refToType.get().getSubtypeSupport() instanceof ExistingSubtypeAspect) {
|
||||
if (subtyping && refToType.get().getSubtypeSupport() != null) {
|
||||
out.comma().append("this");
|
||||
}
|
||||
out.append(')');
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
class ReadDelegate {
|
||||
private static final List<String> STATIC_METHOD_PARAM_NAME_LIST = Collections.singletonList(Util.READER_NAME);
|
||||
private static final List<String> STATIC_METHOD_PARAM_NAME_LIST2 = Arrays.asList(Util.READER_NAME, "nextName");
|
||||
|
||||
private final TypeHandler<?> typeHandler;
|
||||
private final boolean isList;
|
||||
|
||||
ReadDelegate(TypeHandler<?> typeHandler, boolean isList) {
|
||||
private final List<String> paramNames;
|
||||
|
||||
ReadDelegate(@NotNull TypeHandler<?> typeHandler, boolean isList, boolean hasNextNameParam) {
|
||||
this.typeHandler = typeHandler;
|
||||
this.isList = isList;
|
||||
|
||||
paramNames = hasNextNameParam ? STATIC_METHOD_PARAM_NAME_LIST2 : STATIC_METHOD_PARAM_NAME_LIST;
|
||||
}
|
||||
|
||||
void write(ClassScope scope, Method method, TextOutput out) {
|
||||
MethodHandler.writeMethodDeclarationJava(out, method, STATIC_METHOD_PARAM_NAME_LIST);
|
||||
MethodHandler.writeMethodDeclarationJava(out, method, paramNames);
|
||||
out.openBlock();
|
||||
out.append("return ");
|
||||
if (isList) {
|
||||
@@ -24,7 +32,10 @@ class ReadDelegate {
|
||||
}
|
||||
else {
|
||||
typeHandler.writeInstantiateCode(scope, out);
|
||||
out.append("(").append(Util.READER_NAME).append(')');
|
||||
out.append('(').append(Util.READER_NAME);
|
||||
out.comma().space();
|
||||
out.append(paramNames.size() == 1 ? "null" : "nextName");
|
||||
out.append(')');
|
||||
}
|
||||
out.semi();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ReaderGenerator {
|
||||
configuration.getPackageName().replace('.',
|
||||
File.separatorChar),
|
||||
configuration.getClassName() + ".java"));
|
||||
generateImpl(configuration, fileUpdater.builder);
|
||||
generate(configuration, fileUpdater.builder);
|
||||
fileUpdater.update();
|
||||
}
|
||||
|
||||
@@ -96,12 +96,7 @@ public class ReaderGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
return new Params() {
|
||||
@Override
|
||||
public String outputDirectory() {
|
||||
return outputDirParam.getValue();
|
||||
}
|
||||
};
|
||||
return outputDirParam::getValue;
|
||||
}
|
||||
|
||||
private interface ParamListener {
|
||||
@@ -128,12 +123,12 @@ public class ReaderGenerator {
|
||||
}
|
||||
|
||||
protected static GeneratedCodeMap buildParserMap(GenerateConfiguration configuration) {
|
||||
return generateImpl(configuration, new StringBuilder());
|
||||
return generate(configuration, new StringBuilder());
|
||||
}
|
||||
|
||||
private static GeneratedCodeMap generateImpl(GenerateConfiguration configuration, StringBuilder stringBuilder) {
|
||||
return configuration.getParser().generateStaticReader(stringBuilder,
|
||||
configuration.getPackageName(), configuration.getClassName(),
|
||||
configuration.getBasePackagesMap());
|
||||
private static GeneratedCodeMap generate(GenerateConfiguration configuration, StringBuilder stringBuilder) {
|
||||
return configuration.getParser().generateReader(stringBuilder,
|
||||
configuration.getPackageName(), configuration.getClassName(),
|
||||
configuration.getBasePackagesMap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.io.JsonReaderEx;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.io.JsonReaderEx;
|
||||
import org.jetbrains.jsonProtocol.JsonParseMethod;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -32,7 +33,7 @@ class ReaderRoot<R> {
|
||||
Method[] methods = clazz.getMethods();
|
||||
Arrays.sort(methods, new Comparator<Method>() {
|
||||
@Override
|
||||
public int compare(Method o1, Method o2) {
|
||||
public int compare(@NotNull Method o1, @NotNull Method o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
@@ -68,12 +69,12 @@ class ReaderRoot<R> {
|
||||
}
|
||||
|
||||
Type[] arguments = m.getGenericParameterTypes();
|
||||
if (arguments.length != 1) {
|
||||
if (arguments.length > 2) {
|
||||
throw new JsonProtocolModelParseException("Exactly one argument is expected in " + m);
|
||||
}
|
||||
Type argument = arguments[0];
|
||||
if (argument == JsonReaderEx.class || argument == Object.class) {
|
||||
methodMap.put(m, new ReadDelegate(typeHandler, isList));
|
||||
methodMap.put(m, new ReadDelegate(typeHandler, isList, arguments.length != 1));
|
||||
}
|
||||
else {
|
||||
throw new JsonProtocolModelParseException("Unrecognized argument type in " + m);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
/**
|
||||
* Encapsulate subtype aspects of the type.
|
||||
*/
|
||||
abstract class SubtypeAspect {
|
||||
abstract void writeSuperFieldJava(TextOutput out);
|
||||
abstract void writeSuperConstructorParamJava(TextOutput out);
|
||||
abstract void writeSuperConstructorInitialization(TextOutput out);
|
||||
|
||||
abstract void writeParseMethod(String className, ClassScope scope, TextOutput out);
|
||||
|
||||
public abstract void writeInstantiateCode(String className, TextOutput out);
|
||||
|
||||
abstract void writeGetSuperMethodJava(TextOutput out);
|
||||
|
||||
public void setSubtypeCaster(SubtypeCaster subtypeCaster) {
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jsonProtocol.JsonObjectBased;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@@ -16,14 +14,13 @@ class TypeHandler<T> {
|
||||
|
||||
private final List<VolatileFieldBinding> volatileFields;
|
||||
|
||||
/** Method implementation for dynamic proxy. */
|
||||
private final LinkedHashMap<Method, MethodHandler> methodHandlerMap;
|
||||
|
||||
/** Loaders that should read values and save them in field array on parse time. */
|
||||
private final List<FieldLoader> fieldLoaders;
|
||||
|
||||
/** Subtype aspects of the type or null */
|
||||
private final SubtypeAspect subtypeAspect;
|
||||
private final ExistingSubtypeAspect subtypeAspect;
|
||||
|
||||
private final boolean hasLazyFields;
|
||||
|
||||
@@ -37,29 +34,25 @@ class TypeHandler<T> {
|
||||
this.methodHandlerMap = methodHandlerMap;
|
||||
this.fieldLoaders = fieldLoaders;
|
||||
this.hasLazyFields = hasLazyFields;
|
||||
if (jsonSuperClass == null) {
|
||||
subtypeAspect = new AbsentSubtypeAspect();
|
||||
}
|
||||
else {
|
||||
subtypeAspect = new ExistingSubtypeAspect(jsonSuperClass);
|
||||
}
|
||||
subtypeAspect = jsonSuperClass == null ? null : new ExistingSubtypeAspect(jsonSuperClass);
|
||||
}
|
||||
|
||||
public Class<T> getTypeClass() {
|
||||
return typeClass;
|
||||
}
|
||||
|
||||
public SubtypeAspect getSubtypeSupport() {
|
||||
@Nullable
|
||||
public ExistingSubtypeAspect getSubtypeSupport() {
|
||||
return subtypeAspect;
|
||||
}
|
||||
|
||||
public void writeInstantiateCode(ClassScope scope, TextOutput out) {
|
||||
public void writeInstantiateCode(@NotNull ClassScope scope, @NotNull TextOutput out) {
|
||||
writeInstantiateCode(scope, false, out);
|
||||
}
|
||||
|
||||
public void writeInstantiateCode(ClassScope scope, boolean deferredReading, TextOutput out) {
|
||||
public void writeInstantiateCode(@NotNull ClassScope scope, boolean deferredReading, @NotNull TextOutput out) {
|
||||
String className = scope.getTypeImplReference(this);
|
||||
if (deferredReading) {
|
||||
if (deferredReading || subtypeAspect == null) {
|
||||
out.append("new ").append(className);
|
||||
}
|
||||
else {
|
||||
@@ -67,10 +60,10 @@ class TypeHandler<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeStaticClassJava(FileScope fileScope) {
|
||||
public void writeStaticClassJava(@NotNull FileScope fileScope) {
|
||||
TextOutput out = fileScope.getOutput();
|
||||
String valueImplClassName = fileScope.getTypeImplShortName(this);
|
||||
out.append("public static final class ").append(valueImplClassName);
|
||||
out.append("private static final class ").append(valueImplClassName);
|
||||
|
||||
out.append(" implements ").append(getTypeClass().getCanonicalName()).openBlock();
|
||||
|
||||
@@ -89,12 +82,16 @@ class TypeHandler<T> {
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
subtypeAspect.writeSuperFieldJava(out);
|
||||
if (subtypeAspect != null) {
|
||||
subtypeAspect.writeSuperFieldJava(out);
|
||||
}
|
||||
|
||||
writeConstructorMethod(valueImplClassName, classScope, out);
|
||||
out.newLine();
|
||||
|
||||
subtypeAspect.writeParseMethod(valueImplClassName, classScope, out);
|
||||
if (subtypeAspect != null) {
|
||||
subtypeAspect.writeParseMethod(valueImplClassName, classScope, out);
|
||||
}
|
||||
|
||||
for (Map.Entry<Method, MethodHandler> en : methodHandlerMap.entrySet()) {
|
||||
out.newLine();
|
||||
@@ -103,7 +100,9 @@ class TypeHandler<T> {
|
||||
}
|
||||
|
||||
writeBaseMethods(out);
|
||||
subtypeAspect.writeGetSuperMethodJava(out);
|
||||
if (subtypeAspect != null) {
|
||||
subtypeAspect.writeGetSuperMethodJava(out);
|
||||
}
|
||||
out.indentOut().append('}');
|
||||
}
|
||||
|
||||
@@ -132,27 +131,47 @@ class TypeHandler<T> {
|
||||
out.closeBlock();
|
||||
}
|
||||
|
||||
private void writeConstructorMethod(String valueImplClassName, ClassScope classScope, TextOutput out) {
|
||||
out.newLine().append("public ").append(valueImplClassName).append("(").append(Util.JSON_READER_PARAMETER_DEF);
|
||||
subtypeAspect.writeSuperConstructorParamJava(out);
|
||||
private void writeConstructorMethod(@NotNull String valueImplClassName, @NotNull ClassScope classScope, @NotNull TextOutput out) {
|
||||
out.newLine().append(valueImplClassName).append('(').append(Util.JSON_READER_PARAMETER_DEF).comma().append("String name");
|
||||
if (subtypeAspect != null) {
|
||||
subtypeAspect.writeSuperConstructorParamJava(out);
|
||||
}
|
||||
out.append(')').openBlock();
|
||||
|
||||
subtypeAspect.writeSuperConstructorInitialization(out);
|
||||
if (subtypeAspect != null) {
|
||||
subtypeAspect.writeSuperConstructorInitialization(out);
|
||||
}
|
||||
|
||||
if (JsonObjectBased.class.isAssignableFrom(typeClass) || hasLazyFields) {
|
||||
out.append(Util.PENDING_INPUT_READER_NAME).append(" = ").append(Util.READER_NAME).append(".subReader();").newLine();
|
||||
out.append(Util.PENDING_INPUT_READER_NAME).append(" = ").append(Util.READER_NAME).append(".subReader()").semi().newLine();
|
||||
}
|
||||
|
||||
if (fieldLoaders.isEmpty()) {
|
||||
out.append(Util.READER_NAME).append(".skipValue()").semi();
|
||||
}
|
||||
else {
|
||||
out.append(Util.READER_NAME).append(".beginObject();");
|
||||
out.append("if (name == null)").openBlock();
|
||||
{
|
||||
out.append("reader.beginObject()").semi();
|
||||
out.newLine().append("if (reader.hasNext())").openBlock();
|
||||
{
|
||||
out.append("name = reader.nextName()").semi();
|
||||
}
|
||||
out.closeBlock();
|
||||
out.newLine().append("else").openBlock();
|
||||
{
|
||||
out.append("return").semi();
|
||||
}
|
||||
out.closeBlock();
|
||||
}
|
||||
out.closeBlock();
|
||||
out.newLine();
|
||||
|
||||
writeReadFields(out, classScope);
|
||||
|
||||
// we don't read all data if we have lazy fields, so, we should not check end of stream
|
||||
//if (!hasLazyFields) {
|
||||
out.newLine().append(Util.READER_NAME).append(".endObject();");
|
||||
out.newLine().newLine().append(Util.READER_NAME).append(".endObject()").semi();
|
||||
//}
|
||||
}
|
||||
out.closeBlock();
|
||||
@@ -166,16 +185,16 @@ class TypeHandler<T> {
|
||||
out.newLine().append("int i = 0").semi();
|
||||
}
|
||||
|
||||
out.newLine().append("while (reader.hasNext())").openBlock(!hasOnlyOneFieldLoader);
|
||||
if (!hasOnlyOneFieldLoader) {
|
||||
out.append("CharSequence name = reader.nextNameAsCharSequence();");
|
||||
}
|
||||
|
||||
out.newLine().append("do").openBlock();
|
||||
boolean isFirst = true;
|
||||
String operator = "if";
|
||||
for (FieldLoader fieldLoader : fieldLoaders) {
|
||||
if (!isFirst) {
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
String fieldName = fieldLoader.getFieldName();
|
||||
out.newLine().append(operator).append(" (").append(hasOnlyOneFieldLoader ? "reader.nextName()" : "name");
|
||||
out.append(operator).append(" (").append(hasOnlyOneFieldLoader ? "reader.nextName()" : "name");
|
||||
out.append(".equals(\"").append(fieldName).append("\"))").openBlock();
|
||||
{
|
||||
assignField(out, fieldName);
|
||||
@@ -204,6 +223,7 @@ class TypeHandler<T> {
|
||||
out.newLine().append("else").openBlock().append("i++").semi().closeBlock();
|
||||
}
|
||||
out.closeBlock();
|
||||
out.newLine().append("while ((name = reader.nextNameOrNull()) != null)").semi();
|
||||
}
|
||||
|
||||
private static TextOutput assignField(TextOutput out, String fieldName) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.jetbrains.protocolReader;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.WildcardType;
|
||||
@@ -14,12 +16,12 @@ public class Util {
|
||||
public static final String BASE_VALUE_PREFIX = "baseMessage";
|
||||
|
||||
public static final String JSON_READER_CLASS_NAME = "org.jetbrains.io.JsonReaderEx";
|
||||
public static final String JSON_READER_PARAMETER_DEF = JSON_READER_CLASS_NAME + " " + READER_NAME;
|
||||
public static final String JSON_READER_PARAMETER_DEF = JSON_READER_CLASS_NAME + ' ' + READER_NAME;
|
||||
|
||||
/**
|
||||
* Generate Java type name of the passed type. Type may be parameterized.
|
||||
*/
|
||||
public static void writeJavaTypeName(Type arg, TextOutput out) {
|
||||
public static void writeJavaTypeName(@NotNull Type arg, @NotNull TextOutput out) {
|
||||
if (arg instanceof Class) {
|
||||
out.append(((Class<?>)arg).getCanonicalName());
|
||||
}
|
||||
|
||||
@@ -282,6 +282,7 @@ public class ChunkExtractor {
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (key == null) continue;
|
||||
final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
|
||||
if (fallbackAttributeKey != null && isHighlightedAsComment(fallbackAttributeKey)) {
|
||||
return true;
|
||||
@@ -295,6 +296,7 @@ public class ChunkExtractor {
|
||||
if (key == DefaultLanguageHighlighterColors.STRING || key == SyntaxHighlighterColors.STRING) {
|
||||
return true;
|
||||
}
|
||||
if (key == null) continue;
|
||||
final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
|
||||
if (fallbackAttributeKey != null && isHighlightedAsString(fallbackAttributeKey)) {
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,9 +25,10 @@ import java.io.File;
|
||||
@State(
|
||||
name = "UsageViewSettings",
|
||||
storages = {
|
||||
@Storage(
|
||||
file = StoragePathMacros.APP_CONFIG + "/other.xml"
|
||||
)}
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
|
||||
@Storage(file = StoragePathMacros.APP_CONFIG + "/usageView.xml")
|
||||
},
|
||||
storageChooser = LastStorageChooserForWrite.class
|
||||
)
|
||||
public class UsageViewSettings implements PersistentStateComponent<UsageViewSettings> {
|
||||
@NonNls public String EXPORT_FILE_NAME = "report.txt";
|
||||
|
||||
@@ -281,6 +281,9 @@ ide.dfa.time.limit.online.description=Time limit (in milliseconds) that is allow
|
||||
ide.dfa.time.limit.offline=5000
|
||||
ide.dfa.time.limit.offline.description=Time limit (in milliseconds) that is allowed to analyze data flow for one method in Analyze | Inspect Code...
|
||||
|
||||
idea.dfa.live.variables.analysis=true
|
||||
idea.dfa.live.variables.analysis.description=Whether to flush dead variables when they're not needed when performing data flow analysis
|
||||
|
||||
ide.ignore.call.result.inspection.honor.inferred.pure=false
|
||||
ide.ignore.call.result.inspection.honor.inferred.pure.description=Whether inferred @Contract(pure=true) annotations should be taken into account in ''Result of method call ignored'' inspection
|
||||
|
||||
@@ -353,7 +356,6 @@ search.everywhere.configurations=true
|
||||
search.everywhere.settings=false
|
||||
|
||||
svn.use.incoming.optimization=false
|
||||
svn.executable.locale=C.UTF-8
|
||||
svn.lowest.supported.format.for.command.line=1.7.0
|
||||
svn.use.svnkit.for.https.server.certificate.check=true
|
||||
|
||||
|
||||
@@ -378,6 +378,7 @@ public class AllIcons {
|
||||
public static final Icon CollapseAllHover = IconLoader.getIcon("/general/collapseAllHover.png"); // 11x16
|
||||
public static final Icon Combo = IconLoader.getIcon("/general/combo.png"); // 16x16
|
||||
public static final Icon Combo2 = IconLoader.getIcon("/general/combo2.png"); // 16x16
|
||||
public static final Icon Combo3 = IconLoader.getIcon("/general/combo3.png"); // 16x16
|
||||
public static final Icon ComboArrow = IconLoader.getIcon("/general/comboArrow.png"); // 16x16
|
||||
public static final Icon ComboArrowDown = IconLoader.getIcon("/general/comboArrowDown.png"); // 9x5
|
||||
public static final Icon ComboArrowLeft = IconLoader.getIcon("/general/comboArrowLeft.png"); // 5x9
|
||||
|
||||