configurable intelliLang performance

This commit is contained in:
Gregory Shrago
2009-12-02 18:51:29 +03:00
parent f9a621e904
commit 48bb1eef48
6 changed files with 97 additions and 24 deletions
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.AdvancedSettingsUI">
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myRoot" 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="562" height="446"/>
@@ -109,9 +109,44 @@
</grid>
<vspacer id="5c670">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="a5863" layout-manager="GridLayoutManager" row-count="3" 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>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none" title="General Hints"/>
<children>
<component id="34215" class="javax.swing.JCheckBox" binding="myAnalyzeReferencesCheckBox">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Analyze references"/>
</properties>
</component>
<component id="eae73" class="javax.swing.JCheckBox" binding="myIncludeUncomputableOperandsAsCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Include uncomputable operands as literals"/>
</properties>
</component>
<component id="b63a5" class="javax.swing.JCheckBox" binding="myUseDataflowAnalysisIfCheckBox">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<selected value="false"/>
<text value="&amp;Use dataflow analysis (slow) "/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<buttonGroups>
@@ -53,6 +53,9 @@ public class AdvancedSettingsUI implements Configurable {
private JPanel myLanguageAnnotationPanel;
private JPanel myPatternAnnotationPanel;
private JPanel mySubstAnnotationPanel;
private JCheckBox myAnalyzeReferencesCheckBox;
private JCheckBox myUseDataflowAnalysisIfCheckBox;
private JCheckBox myIncludeUncomputableOperandsAsCheckBox;
private final ReferenceEditorWithBrowseButton myAnnotationField;
private final ReferenceEditorWithBrowseButton myPatternField;
@@ -126,6 +129,15 @@ public class AdvancedSettingsUI implements Configurable {
if (!mySubstField.getText().equals(myConfiguration.getSubstAnnotationClass())) {
return true;
}
if (myConfiguration.isResolveReferences() != myAnalyzeReferencesCheckBox.isSelected()) {
return true;
}
if (myConfiguration.isUseDfaIfAvailable() != myUseDataflowAnalysisIfCheckBox.isSelected()) {
return true;
}
if (myConfiguration.isIncludeUncomputablesAsLiterals() != myIncludeUncomputableOperandsAsCheckBox.isSelected()) {
return true;
}
return false;
}
@@ -144,6 +156,10 @@ public class AdvancedSettingsUI implements Configurable {
myConfiguration.setLanguageAnnotation(myAnnotationField.getText());
myConfiguration.setPatternAnnotation(myPatternField.getText());
myConfiguration.setSubstAnnotation(mySubstField.getText());
myConfiguration.setResolveReferences(myAnalyzeReferencesCheckBox.isSelected());
myConfiguration.setUseDfaIfAvailable(myUseDataflowAnalysisIfCheckBox.isSelected());
myConfiguration.setIncludeUncomputablesAsLiterals(myIncludeUncomputableOperandsAsCheckBox.isSelected());
}
public void reset() {
@@ -154,6 +170,10 @@ public class AdvancedSettingsUI implements Configurable {
myNoInstrumentation.setSelected(myConfiguration.getInstrumentation() == Configuration.InstrumentationType.NONE);
myAssertInstrumentation.setSelected(myConfiguration.getInstrumentation() == Configuration.InstrumentationType.ASSERT);
myExceptionInstrumentation.setSelected(myConfiguration.getInstrumentation() == Configuration.InstrumentationType.EXCEPTION);
myAnalyzeReferencesCheckBox.setSelected(myConfiguration.isResolveReferences());
myUseDataflowAnalysisIfCheckBox.setSelected(myConfiguration.isUseDfaIfAvailable());
myIncludeUncomputableOperandsAsCheckBox.setSelected(myConfiguration.isIncludeUncomputablesAsLiterals());
}
public void disposeUIResources() {
@@ -77,6 +77,8 @@ public final class Configuration implements PersistentStateComponent<Element> {
@NonNls private static final String SUBST_ANNOTATION_NAME = "SUBST_ANNOTATION";
@NonNls private static final String ENTRY_NAME = "entry";
@NonNls private static final String RESOLVE_REFERENCES = "RESOLVE_REFERENCES";
@NonNls private static final String USE_DFA_IF_AVAILABLE = "USE_DFA_IF_AVAILABLE";
@NonNls private static final String INCLUDE_UNCOMPUTABLES_AS_LITERALS = "INCLUDE_UNCOMPUTABLES_AS_LITERALS";
private final Map<String, List<BaseInjection>> myInjections = new ConcurrentFactoryMap<String, List<BaseInjection>>() {
@Override
@@ -94,6 +96,8 @@ public final class Configuration implements PersistentStateComponent<Element> {
@NotNull private String mySubstAnnotation;
private boolean myResolveReferences;
private boolean myIncludeUncomputablesAsLiterals;
private boolean myUseDfaIfAvailable;
// cached annotation name pairs
private Pair<String, ? extends Set<String>> myLanguageAnnotationPair;
@@ -144,9 +148,10 @@ public final class Configuration implements PersistentStateComponent<Element> {
setLanguageAnnotation(JDOMExternalizerUtil.readField(element, LANGUAGE_ANNOTATION_NAME));
setPatternAnnotation(JDOMExternalizerUtil.readField(element, PATTERN_ANNOTATION_NAME));
setSubstAnnotation(JDOMExternalizerUtil.readField(element, SUBST_ANNOTATION_NAME));
final String resolveReferences = JDOMExternalizerUtil.readField(element, RESOLVE_REFERENCES);
setResolveReferences(resolveReferences == null || Boolean.parseBoolean(resolveReferences));
setResolveReferences(readBoolean(element, RESOLVE_REFERENCES, true));
setUseDfaIfAvailable(readBoolean(element, USE_DFA_IF_AVAILABLE, true));
setIncludeUncomputablesAsLiterals(readBoolean(element, INCLUDE_UNCOMPUTABLES_AS_LITERALS, true));
if (mergeWithOriginalAndCompile) {
mergeWithDefaultConfiguration();
@@ -158,6 +163,12 @@ public final class Configuration implements PersistentStateComponent<Element> {
}
}
private static boolean readBoolean(Element element, String key, boolean defValue) {
final String value = JDOMExternalizerUtil.readField(element, key);
if (value == null) return defValue;
return Boolean.parseBoolean(value);
}
private void mergeWithDefaultConfiguration() {
Configuration cfg = null;
try {
@@ -363,6 +374,22 @@ public final class Configuration implements PersistentStateComponent<Element> {
myResolveReferences = resolveReferences;
}
public boolean isIncludeUncomputablesAsLiterals() {
return myIncludeUncomputablesAsLiterals;
}
public void setIncludeUncomputablesAsLiterals(boolean flag) {
myIncludeUncomputablesAsLiterals = flag;
}
public boolean isUseDfaIfAvailable() {
return myUseDfaIfAvailable;
}
public void setUseDfaIfAvailable(boolean flag) {
myUseDfaIfAvailable = flag;
}
@Nullable
public BaseInjection findExistingInjection(@NotNull final BaseInjection injection) {
final List<BaseInjection> list = getInjections(injection.getSupportId());
@@ -220,7 +220,9 @@ public class PatternValidator extends LocalInspectionTool {
if (pattern == null) return;
List<PsiExpression> nonConstantElements = new SmartList<PsiExpression>();
String o = SubstitutedExpressionEvaluationHelper.computeExpression(expression, nonConstantElements);
final Object result = new SubstitutedExpressionEvaluationHelper(expression.getProject()).computeExpression(
expression, myConfiguration.isUseDfaIfAvailable(), false, nonConstantElements);
final String o = result == null ? null : String.valueOf(result);
if (o != null) {
if (!pattern.matcher(o).matches()) {
if (annotations.length > 1) {
@@ -95,7 +95,7 @@ public class ContextComputationProcessor {
}
else {
final SmartList<PsiExpression> uncomputables = new SmartList<PsiExpression>();
final Object o = expression instanceof PsiExpression? myEvaluationHelper.computeExpression((PsiExpression)expression, true, uncomputables) : null;
final Object o = expression instanceof PsiExpression? myEvaluationHelper.computeExpression((PsiExpression)expression, uncomputables) : null;
if (uncomputables.size() > 0) {
unparsable.set(Boolean.TRUE);
}
@@ -23,10 +23,10 @@ import com.intellij.psi.*;
import com.intellij.psi.util.CachedValue;
import com.intellij.util.containers.ConcurrentHashMap;
import org.intellij.plugins.intelliLang.Configuration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
@@ -47,11 +47,11 @@ public class SubstitutedExpressionEvaluationHelper {
myConfiguration = Configuration.getInstance();
}
public Object computeExpression(final PsiExpression e, final boolean includeUncomputablesAsLiterals) {
return computeExpression(e, includeUncomputablesAsLiterals, null);
public Object computeExpression(final PsiExpression e, final List<PsiExpression> uncomputables) {
return computeExpression(e, myConfiguration.isUseDfaIfAvailable(), myConfiguration.isIncludeUncomputablesAsLiterals(), uncomputables);
}
public Object computeExpression(final PsiExpression e, final boolean includeUncomputablesAsLiterals, final List<PsiExpression> uncomputables) {
public Object computeExpression(final PsiExpression e, final boolean useDfa, final boolean includeUncomputablesAsLiterals, final List<PsiExpression> uncomputables) {
final ConcurrentMap<PsiElement, Object> map = new ConcurrentHashMap<PsiElement, Object>();
//if (true) return myHelper.computeConstantExpression(e, false);
return myHelper.computeExpression(e, false, new PsiConstantEvaluationHelper.AuxEvaluator() {
@@ -77,7 +77,8 @@ public class SubstitutedExpressionEvaluationHelper {
if (substituted != null) return substituted;
if (resolved instanceof PsiVariable) {
resolvedType = ((PsiVariable)resolved).getType();
final Collection<PsiExpression> values = DfaUtil.getCachedVariableValues(((PsiVariable)resolved), o);
final Collection<PsiExpression> values =
!useDfa? Collections.<PsiExpression>emptyList() : DfaUtil.getCachedVariableValues(((PsiVariable)resolved), o);
// return the first computed value as far as we do not support multiple injection
for (PsiExpression value : values) {
final Object computedValue = auxEvaluator.computeExpression(value, this);
@@ -126,16 +127,4 @@ public class SubstitutedExpressionEvaluationHelper {
return null;
}
/**
* Computes the value for the passed expression.
*
* @param e The expression whose value to compute
* @param nonConstant list that returns non-constant and non-substituted expressions
* @return the computed value, or null if the expression isn't compile time constant and not susbtituted
*/
@Nullable
public static String computeExpression(@NotNull final PsiExpression e, @Nullable List<PsiExpression> nonConstant) {
final Object result = new SubstitutedExpressionEvaluationHelper(e.getProject()).computeExpression(e, false, nonConstant);
return result == null? null : String.valueOf(result);
}
}