Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir.Orlov
2017-02-06 17:01:05 +03:00
23 changed files with 260 additions and 169 deletions
@@ -15,8 +15,11 @@
*/
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -178,6 +181,33 @@ public class JavaHighlightUtil {
}
}
@Nullable
public static String checkPsiTypeUseInContext(@Nullable PsiType type, @NotNull PsiElement context) {
if (type instanceof PsiPrimitiveType) return null;
if (type instanceof PsiArrayType) return checkPsiTypeUseInContext(((PsiArrayType) type).getComponentType(), context);
if (PsiUtil.resolveClassInType(type) != null) return null;
if (type instanceof PsiClassType) return checkClassType((PsiClassType)type, context);
return "Invalid Java type";
}
private static String checkClassType(@NotNull PsiClassType type, @NotNull PsiElement context) {
String className = PsiNameHelper.getQualifiedClassName(type.getCanonicalText(false), true);
if (classExists(context, className)) {
return getClassInaccessibleMessage(context, className);
}
return "Invalid Java type";
}
private static boolean classExists(@NotNull PsiElement context, String className) {
return JavaPsiFacade.getInstance(context.getProject()).findClass(className, GlobalSearchScope.allScope(context.getProject())) != null;
}
@NotNull
private static String getClassInaccessibleMessage(@NotNull PsiElement context, String className) {
Module module = ModuleUtilCore.findModuleForPsiElement(context);
return "Class '" + className + "' is not accessible " + (module == null ? "here" : "from module '" + module.getName() + "'");
}
static class ConstructorVisitorInfo {
List<PsiMethod> visitedConstructors;
PsiMethod recursivelyCalledConstructor;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -57,11 +57,13 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
}
final ArrayList<ReferenceData> array = new ArrayList<>();
int refOffset = 0; // this is an offset delta for conversion from absolute offset to an offset inside clipboard contents
for (int j = 0; j < startOffsets.length; j++) {
final int startOffset = startOffsets[j];
for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffsets[j])) {
addReferenceData(file, startOffset, element, array);
refOffset += startOffsets[j];
for (final PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffsets[j], endOffsets[j])) {
addReferenceData(file, refOffset, element, array);
}
refOffset -= endOffsets[j] + 1; // 1 accounts for line break inserted between contents corresponding to different carets
}
if (array.isEmpty()) {
@@ -39,7 +39,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -123,8 +122,6 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel {
@Override
public void apply(CodeStyleSettings settings) {
myMatchingRulesPanel.hideEditor();
CommonCodeStyleSettings commonSettings = settings.getCommonSettings(myLanguage);
commonSettings.setArrangementSettings(createSettings());
if (myForceArrangementPanel != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -46,16 +46,20 @@ public class CopyPasteFoldingProcessor extends CopyPastePostProcessor<FoldingTra
final FoldRegion[] regions = editor.getFoldingModel().getAllFoldRegions();
for (final FoldRegion region : regions) {
if (!region.isValid()) continue;
int refOffset = 0;
for (int j = 0; j < startOffsets.length; j++) {
refOffset += startOffsets[j];
if (startOffsets[j] <= region.getStartOffset() && region.getEndOffset() <= endOffsets[j]) {
list.add(
new FoldingData(
region.getStartOffset() - startOffsets[j],
region.getEndOffset() - startOffsets[j],
region.getStartOffset() - refOffset, // offsets should be relative to clipboard contents start
region.getEndOffset() - refOffset,
region.isExpanded()
)
);
break;
}
refOffset -= endOffsets[j] + 1; // 1 accounts for line break inserted between contents corresponding to different carets
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl;
import java.util.Collections;
@@ -35,17 +36,20 @@ public class AfterCallInstruction extends InstructionImpl {
return super.toString() + "AFTER CALL " + myCall.num();
}
@NotNull
@Override
public Iterable<? extends Instruction> allPredecessors() {
public Iterable<Instruction> allPredecessors() {
return Collections.singletonList(myReturnInstruction);
}
@NotNull
@Override
public Iterable<? extends Instruction> predecessors(CallEnvironment environment) {
public Iterable<Instruction> predecessors(@NotNull CallEnvironment environment) {
environment.callStack(myReturnInstruction).push(myCall);
return Collections.singletonList(myReturnInstruction);
}
@NotNull
@Override
protected String getElementPresentation() {
return "";
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,18 +15,21 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import org.jetbrains.annotations.NotNull;
import java.util.Deque;
/**
* @author ven
* @see org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder#visitTryStatement(org.jetbrains.plugins.groovy.lang.psi.api.statements.GrTryCatchStatement)
* @see ReturnInstruction#successors(CallEnvironment)
* @see CallInstruction#successors(CallEnvironment)
* @see AfterCallInstruction#predecessors(CallEnvironment)
*
* @author ven
*/
public interface CallEnvironment {
Deque<CallInstruction> callStack(Instruction instruction);
void update(Deque<CallInstruction> callStack, Instruction instruction);
@NotNull
Deque<CallInstruction> callStack(@NotNull Instruction instruction);
void update(@NotNull Deque<CallInstruction> callStack, @NotNull Instruction instruction);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl;
import java.util.Collections;
@@ -34,17 +35,20 @@ public class CallInstruction extends InstructionImpl {
return super.toString() + " CALL " + myCallee.num();
}
@NotNull
@Override
public Iterable<? extends Instruction> successors(CallEnvironment environment) {
public Iterable<Instruction> successors(@NotNull CallEnvironment environment) {
environment.callStack(myCallee).push(this);
return Collections.singletonList(myCallee);
}
@NotNull
@Override
public Iterable<? extends Instruction> allSuccessors() {
public Iterable<Instruction> allSuccessors() {
return Collections.singletonList(myCallee);
}
@NotNull
@Override
protected String getElementPresentation() {
return "";
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,6 +37,7 @@ public abstract class GotoInstruction extends InstructionImpl {
return myCondition;
}
@NotNull
@Override
protected String getElementPresentation() {
return " Positive goto instruction, condition=" + myCondition.num() + getElement();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
@@ -28,17 +29,26 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ConditionInstruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl;
import java.util.Objects;
/**
* @author peter
*/
public class InstanceOfInstruction extends InstructionImpl implements MixinTypeInstruction {
private final ConditionInstruction myCondition;
public InstanceOfInstruction(GrExpression assertion, ConditionInstruction cond) {
public InstanceOfInstruction(@NotNull GrExpression assertion, ConditionInstruction cond) {
super(assertion);
myCondition = cond;
}
@NotNull
@Override
public PsiElement getElement() {
return Objects.requireNonNull(super.getElement());
}
@NotNull
@Override
protected String getElementPresentation() {
return "instanceof: " + getElement().getText();
@@ -57,6 +67,7 @@ public class InstanceOfInstruction extends InstructionImpl implements MixinTypeI
else if (element instanceof GrBinaryExpression && ControlFlowBuilderUtil.isInstanceOfBinary((GrBinaryExpression)element)) {
GrExpression left = ((GrBinaryExpression)element).getLeftOperand();
GrExpression right = ((GrBinaryExpression)element).getRightOperand();
if (right == null) return null;
GroovyResolveResult result = ((GrReferenceExpression)right).advancedResolve();
final PsiElement resolved = result.getElement();
if (resolved instanceof PsiClass) {
@@ -76,6 +87,7 @@ public class InstanceOfInstruction extends InstructionImpl implements MixinTypeI
return instanceOf.getSecond();
}
@Nullable
@Override
public ReadWriteVariableInstruction getInstructionToMixin(Instruction[] flow) {
Pair<GrExpression, PsiType> instanceOf = getInstanceof();
@@ -97,6 +109,7 @@ public class InstanceOfInstruction extends InstructionImpl implements MixinTypeI
return instanceOf.getFirst().getText();
}
@Nullable
@Override
public ConditionInstruction getConditionInstruction() {
return myCondition;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -23,11 +23,18 @@ import org.jetbrains.annotations.Nullable;
* @author ven
*/
public interface Instruction {
Iterable<? extends Instruction> successors(CallEnvironment environment);
Iterable<? extends Instruction> predecessors(CallEnvironment environment);
Iterable<? extends Instruction> allSuccessors();
Iterable<? extends Instruction> allPredecessors();
@NotNull
Iterable<Instruction> successors(@NotNull CallEnvironment environment);
@NotNull
Iterable<Instruction> predecessors(@NotNull CallEnvironment environment);
@NotNull
Iterable<Instruction> allSuccessors();
@NotNull
Iterable<Instruction> allPredecessors();
int num();
@@ -36,5 +43,4 @@ public interface Instruction {
@Nullable
PsiElement getElement();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -28,6 +28,7 @@ public class NegatingGotoInstruction extends GotoInstruction {
super(element, condition);
}
@NotNull
@Override
protected String getElementPresentation() {
return " Negating goto instruction, condition=" + getCondition().num() + getElement();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@ public class ReadWriteVariableInstruction extends InstructionImpl {
return myIsWrite;
}
@NotNull
@Override
protected String getElementPresentation() {
return (isWrite() ? "WRITE " : "READ ") + myName;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrFinallyClause;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl;
@@ -34,18 +35,20 @@ public class ReturnInstruction extends InstructionImpl {
return super.toString() + " RETURN";
}
@NotNull
@Override
protected String getElementPresentation() {
return "";
}
@NotNull
@Override
public Iterable<? extends Instruction> successors(CallEnvironment environment) {
public Iterable<Instruction> successors(@NotNull CallEnvironment environment) {
final Deque<CallInstruction> callStack = environment.callStack(this);
if (callStack.isEmpty()) return Collections.emptyList(); //can be true in case env was not populated (e.g. by DFA)
final CallInstruction callInstruction = callStack.peek();
final Iterable<? extends Instruction> successors = callInstruction.allSuccessors();
final Iterable<Instruction> successors = callInstruction.allSuccessors();
final Deque<CallInstruction> copy = new ArrayDeque<>(callStack);
copy.pop();
for (Instruction instruction : successors) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -81,17 +81,19 @@ public class ArgumentInstruction extends InstructionImpl implements MixinTypeIns
return false;
}
private static GrCall findCall(PsiElement element) {
PsiElement parent = element.getParent().getParent();
if (!(parent instanceof GrCall)) {
private static GrCall findCall(@NotNull PsiElement element) {
PsiElement parent = element.getParent();
PsiElement pParent = parent == null ? null : parent.getParent();
if (!(pParent instanceof GrCall)) {
LOG.error("elemText: " + element.getText() +
"\nisValid = " + element.isValid() +
"\nParent = " + (element.getParent() == null ? "null" : element.getParent().getClass()) +
"\nPParent = " + (parent == null ? "null" : parent.getClass()));
"\nParent = " + (parent == null ? "null" : parent.getClass()) +
"\nPParent = " + (pParent == null ? "null" : pParent.getClass()));
}
return (GrCall)parent;
return (GrCall)pParent;
}
@Nullable
@Override
public ReadWriteVariableInstruction getInstructionToMixin(Instruction[] flow) {
Instruction instruction = ControlFlowUtils.findInstruction(getElement(), flow);
@@ -103,17 +105,20 @@ public class ArgumentInstruction extends InstructionImpl implements MixinTypeIns
}
}
@Nullable
@Override
public String getVariableName() {
//noinspection ConstantConditions
return ((GrReferenceExpression)getElement()).getReferenceName();
}
@Nullable
@Override
public ConditionInstruction getConditionInstruction() {
return null;
}
@NotNull
@Override
protected String getElementPresentation() {
return "ARGUMENT " + super.getElementPresentation();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -38,6 +38,7 @@ public class ConditionInstruction extends InstructionImpl implements Instruction
myDependent.add(this);
}
@NotNull
@Override
protected String getElementPresentation() {
StringBuilder builder = new StringBuilder();
@@ -1,27 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
/**
* @author Max Medvedev
*/
public class FakeInstruction extends InstructionImpl implements Instruction {
public FakeInstruction(int num) {
super(null);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
/**
@@ -25,11 +27,13 @@ public class IfEndInstruction extends InstructionImpl{
super(ifStatement);
}
@Nullable
@Override
public GrIfStatement getElement() {
return (GrIfStatement)super.getElement();
}
@NotNull
@Override
protected String getElementPresentation() {
return "End element: " + myPsiElement;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 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.
@@ -31,8 +31,8 @@ import java.util.LinkedHashSet;
* @author ven
*/
public class InstructionImpl implements Instruction {
private final LinkedHashSet<InstructionImpl> myPredecessors = new LinkedHashSet<>(1);
private final LinkedHashSet<InstructionImpl> mySuccessors = new LinkedHashSet<>(1);
private final LinkedHashSet<Instruction> myPredecessors = new LinkedHashSet<>(1);
private final LinkedHashSet<Instruction> mySuccessors = new LinkedHashSet<>(1);
private LinkedHashSet<NegatingGotoInstruction> myNegations;
protected final PsiElement myPsiElement;
@@ -48,33 +48,35 @@ public class InstructionImpl implements Instruction {
myPsiElement = element;
}
@NotNull
@Override
public Iterable<? extends Instruction> successors(CallEnvironment environment) {
public Iterable<Instruction> successors(@NotNull CallEnvironment environment) {
final Deque<CallInstruction> stack = environment.callStack(this);
for (InstructionImpl instruction : mySuccessors) {
for (Instruction instruction : mySuccessors) {
environment.update(stack, instruction);
}
return mySuccessors;
}
@NotNull
@Override
public Iterable<? extends Instruction> predecessors(CallEnvironment environment) {
public Iterable<Instruction> predecessors(@NotNull CallEnvironment environment) {
final Deque<CallInstruction> stack = environment.callStack(this);
for (InstructionImpl instruction : myPredecessors) {
for (Instruction instruction : myPredecessors) {
environment.update(stack, instruction);
}
return myPredecessors;
}
@NotNull
@Override
public Iterable<? extends Instruction> allSuccessors() {
public Iterable<Instruction> allSuccessors() {
return mySuccessors;
}
@NotNull
@Override
public Iterable<? extends Instruction> allPredecessors() {
public Iterable<Instruction> allPredecessors() {
return myPredecessors;
}
@@ -82,8 +84,8 @@ public class InstructionImpl implements Instruction {
final StringBuilder builder = new StringBuilder();
builder.append(myNumber);
builder.append("(");
for (InstructionImpl successor : mySuccessors) {
builder.append(successor.myNumber);
for (Instruction successor : mySuccessors) {
builder.append(successor.num());
builder.append(',');
}
if (!mySuccessors.isEmpty()) builder.delete(builder.length() - 1, builder.length());
@@ -91,6 +93,7 @@ public class InstructionImpl implements Instruction {
return builder.toString();
}
@NotNull
protected String getElementPresentation() {
//return "element: " + (myPsiElement != null ? myPsiElement.getText() : null);
return "element: " + myPsiElement;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,8 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.dataFlow;
import com.intellij.codeInspection.dataFlow.WorkingTimeMeasurer;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.CallEnvironment;
@@ -33,11 +32,12 @@ import java.util.*;
public class DFAEngine<E> {
private final Instruction[] myFlow;
private final DfaInstance<E> myDfa;
private final Semilattice<E> mySemilattice;
public DFAEngine(Instruction[] flow, DfaInstance<E> dfa, Semilattice<E> semilattice) {
private WorkCounter myCounter = null;
public DFAEngine(@NotNull Instruction[] flow, @NotNull DfaInstance<E> dfa, @NotNull Semilattice<E> semilattice) {
myFlow = flow;
myDfa = dfa;
mySemilattice = semilattice;
@@ -53,13 +53,14 @@ public class DFAEngine<E> {
}
}
@NotNull
@Override
public Deque<CallInstruction> callStack(Instruction instruction) {
public Deque<CallInstruction> callStack(@NotNull Instruction instruction) {
return myEnv.get(instruction.num());
}
@Override
public void update(Deque<CallInstruction> callStack, Instruction instruction) {
public void update(@NotNull Deque<CallInstruction> callStack, @NotNull Instruction instruction) {
myEnv.set(instruction.num(), callStack);
}
}
@@ -78,73 +79,70 @@ public class DFAEngine<E> {
@Nullable
private List<E> performDFA(boolean timeout) {
WorkingTimeMeasurer measurer = null;
final int n = myFlow.length;
final List<E> info = new ArrayList<>(Collections.nCopies(n, myDfa.initial()));
final CallEnvironment env = new MyCallEnvironment(n);
ArrayList<E> info = new ArrayList<>(Collections.nCopies(myFlow.length, myDfa.initial()));
CallEnvironment env = new MyCallEnvironment(myFlow.length);
boolean[] visited = new boolean[myFlow.length];
final WorkList workList = new WorkList(n);
final boolean forward = myDfa.isForward();
int[] order = ControlFlowBuilderUtil.postorder(myFlow); //todo for backward?
int count = 0;
for (int i = forward ? 0 : myFlow.length - 1; forward ? i < myFlow.length : i >= 0;) {
Instruction instr = myFlow[order[i]];
final int[] flowOrder = getFlowOrder();
for (int i : flowOrder) {
if (!workList.offer(myFlow[i])) continue;
if (!visited[instr.num()]) {
Queue<Instruction> workList = new LinkedList<>();
workList.add(instr);
visited[instr.num()] = true;
while (!workList.isEmpty()) {
count++;
if (timeout && count % 512 == 0) {
if (measurer == null) {
long msLimit = Registry.intValue("ide.dfa.time.limit.online");
measurer = new WorkingTimeMeasurer(msLimit * 1000 * 1000);
}
else if (measurer.isTimeOver()) {
return null;
}
}
ProgressManager.checkCanceled();
final Instruction curr = workList.remove();
final int num = curr.num();
final E oldE = info.get(num);
E newE = join(curr, info, env);
myDfa.fun(newE, curr);
if (!mySemilattice.eq(newE, oldE)) {
info.set(num, newE);
for (Instruction next : getNext(curr, env)) {
workList.add(next);
visited[next.num()] = true;
}
while (!workList.isEmpty()) {
ProgressManager.checkCanceled();
if (timeout && checkCounter()) return null;
final Instruction curr = workList.remove();
final int num = curr.num();
final E oldE = info.get(num); // saved outbound state
final E newE = getInboundState(curr, info, env); // inbound state
myDfa.fun(newE, curr); // newly modified outbound state
if (!mySemilattice.eq(newE, oldE)) { // if outbound state changed
info.set(num, newE); // save new state
for (Instruction next : getNext(curr, env)) {
workList.offerUnconditionally(next);
}
}
}
if (forward) i++;
else i--;
}
return info;
}
private int[] getFlowOrder() {
int[] order = ControlFlowBuilderUtil.postorder(myFlow);
if (myDfa.isForward()) {
return order;
}
else {
return ArrayUtil.reverseArray(order);
}
}
@NotNull
private E join(@NotNull Instruction instruction, @NotNull List<E> info, @NotNull CallEnvironment env) {
final Iterable<? extends Instruction> prev = myDfa.isForward() ? instruction.predecessors(env) : instruction.successors(env);
ArrayList<E> prevInfos = new ArrayList<>();
for (Instruction i : prev) {
private E getInboundState(@NotNull Instruction instruction, @NotNull List<E> info, @NotNull CallEnvironment env) {
List<E> prevInfos = new ArrayList<>();
for (Instruction i : getPrevious(instruction, env)) {
prevInfos.add(info.get(i.num()));
}
return mySemilattice.join(prevInfos);
}
private Iterable<? extends Instruction> getNext(Instruction curr, CallEnvironment env) {
return myDfa.isForward() ? curr.successors(env) : curr.predecessors(env);
@NotNull
private Iterable<Instruction> getPrevious(@NotNull Instruction instruction, @NotNull CallEnvironment env) {
return myDfa.isForward() ? instruction.predecessors(env) : instruction.successors(env);
}
@NotNull
private Iterable<Instruction> getNext(@NotNull Instruction instruction, @NotNull CallEnvironment env) {
return myDfa.isForward() ? instruction.successors(env) : instruction.predecessors(env);
}
private boolean checkCounter() {
if (myCounter == null) {
myCounter = new WorkCounter();
return false;
}
return myCounter.isTimeOver();
}
}
@@ -13,20 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.roots;
import com.intellij.openapi.roots.ui.configuration.JdkComboBox;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.testFramework.LightPlatformTestCase;
/**
* @author Dmitry Avdeev
*/
public class JdkComboBoxTest extends LightPlatformTestCase {
package org.jetbrains.plugins.groovy.lang.psi.dataFlow
public void testSuggestedSdks() throws Exception {
JdkComboBox comboBox = new JdkComboBox(new ProjectSdksModel(), null, null, null, true);
Object itemAt = comboBox.getItemAt(0);
System.out.println(itemAt);
import com.intellij.codeInspection.dataFlow.WorkingTimeMeasurer
import com.intellij.openapi.util.registry.Registry
internal class WorkCounter {
private val myMeasurer by lazy(LazyThreadSafetyMode.NONE) {
val msLimit = Registry.intValue("ide.dfa.time.limit.online").toLong()
WorkingTimeMeasurer(msLimit * 1000 * 1000)
}
}
private var myCount: Int = 0
/**
* Checks [WorkingTimeMeasurer.isTimeOver] every 512 invocations
* @return `true` if time is over
*/
fun isTimeOver(): Boolean = ++myCount % 512 == 0 && myMeasurer.isTimeOver
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.psi.dataFlow
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction
import java.util.*
internal class WorkList(size: Int) {
private val myQueue: Queue<Instruction> = LinkedList<Instruction>()
private val myVisited: BooleanArray = BooleanArray(size)
fun remove(): Instruction = myQueue.remove()
val isEmpty: Boolean get() = myQueue.isEmpty()
/**
* Adds element to the queue and marks it as visited
*/
fun offerUnconditionally(instruction: Instruction) {
myQueue.add(instruction)
myVisited[instruction.num()] = true
}
/**
* Adds element to the queue and marks it as visited if it wasn't visited before
* @return `true` if element was added to the queue
*/
fun offer(instruction: Instruction): Boolean {
if (myVisited[instruction.num()]) return false
offerUnconditionally(instruction)
return true
}
}
@@ -62,13 +62,6 @@ class PyCharmEduProperties extends PyCharmPropertiesBase {
"PyCharm Edu"
}
@Override
void copyAdditionalFiles(BuildContext context, String targetDirectory) {
super.copyAdditionalFiles(context, targetDirectory)
context.ant.copy(file: "$context.paths.projectHome/help/pycharm-eduhelp.jar", todir: "$targetDirectory/help",
failonerror: false, quiet: true)
}
@Override
String getBaseDownloadUrlForJre() { "https://download.jetbrains.com/python" }
}
@@ -86,11 +79,6 @@ class PyCharmEduProperties extends PyCharmPropertiesBase {
"pycharm-edu-${applicationInfo.isEAP ? buildNumber : applicationInfo.fullVersion}"
}
@Override
void copyAdditionalFiles(BuildContext context, String targetDirectory) {
context.ant.copy(file: "$context.paths.projectHome/help/pycharm-eduhelp.jar", todir: "$targetDirectory/help",
failonerror: false, quiet: true)
}
}
}
@@ -100,7 +88,6 @@ class PyCharmEduProperties extends PyCharmPropertiesBase {
{
icnsPath = "$pythonCommunityPath/educational-python/resources/PyCharmEdu.icns"
bundleIdentifier = "com.jetbrains.pycharm"
helpId = "PE"
dmgImagePath = "$pythonCommunityPath/educational-python/build/DMG_background.png"
}
}
@@ -17,7 +17,7 @@
<update-urls check="http://www.jetbrains.com/updates/updates.xml"
patches="http://download.jetbrains.com/python/"/>
<help file="pycharmhelp.jar" root="pycharm"/>
<help webhelp-url="https://www.jetbrains.com/help/pycharm-edu"/>
<documentation url="https://www.jetbrains.com/pycharm-edu/quickstart/"/>
<support url="https://intellij-support.jetbrains.com/hc/en-us#"/>
<feedback eap-url="https://youtrack.jetbrains.com/newissue?project=EDU&amp;clearDraft=true&amp;c=Affected+versions+$BUILD&amp;description=$DESCR"