Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2014-10-14 23:35:59 +04:00
39 changed files with 543 additions and 262 deletions
@@ -165,8 +165,8 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
@Override
public void writeSettings(@NotNull Element node) throws WriteExternalException {
super.writeSettings(node);
myLocalInspectionBase.writeSettings(node);
super.writeSettings(node);
for (EntryPoint extension : myExtensions) {
extension.writeExternal(node);
}
@@ -16,79 +16,15 @@
package com.intellij.codeInspection.deadCode;
import com.intellij.codeInspection.ex.InspectionElementsMerger;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.ToolsImpl;
import com.intellij.lang.annotation.HighlightSeverity;
import org.jdom.Element;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class UnusedDeclarationInspectionMerger extends InspectionElementsMerger {
@Override
public String getNewToolName() {
public String getMergedToolName() {
return UnusedDeclarationInspectionBase.SHORT_NAME;
}
@Override
public Element merge(Map<String, Element> elements) {
final Element unusedSymbolElement = elements.get("UNUSED_SYMBOL");
final Element unusedDeclarationElement = elements.get("UnusedDeclaration");
if (unusedDeclarationElement != null || unusedSymbolElement != null) {
final Element toolElement = new Element(InspectionProfileImpl.INSPECTION_TOOL_TAG);
final LinkedHashMap<String, Element> scopes = new LinkedHashMap<String, Element>();
final List<Element> content = new ArrayList<Element>();
boolean enabled = cloneContent(unusedDeclarationElement, content, scopes);
enabled |= cloneContent(unusedSymbolElement, content, scopes);
toolElement.setAttribute(InspectionProfileImpl.CLASS_TAG, getNewToolName());
toolElement.setAttribute(ToolsImpl.ENABLED_ATTRIBUTE, String.valueOf(enabled));
String level = getLevel(unusedSymbolElement);
if (level == null) {
level = getLevel(unusedDeclarationElement);
}
if (level != null) {
toolElement.setAttribute(ToolsImpl.LEVEL_ATTRIBUTE, level);
}
for (Element scopeEl : scopes.values()) {
toolElement.addContent(scopeEl);
}
for (Element element : content) {
toolElement.addContent(element);
}
return toolElement;
}
return null;
}
private static String getLevel(Element element) {
return element != null ? element.getAttributeValue(ToolsImpl.LEVEL_ATTRIBUTE) : HighlightSeverity.WARNING.getName();
}
protected static boolean cloneContent(Element sourceElement, List<Element> elements, Map<String, Element> scopes) {
if (sourceElement != null) {
for (Element element : sourceElement.getChildren()) {
if ("scope".equals(element.getName())) {
String scopeName = element.getAttributeValue("name");
if (scopes.containsKey(scopeName)) {
Element scopeElement = scopes.get(scopeName);
for (Element scopeEl : element.getChildren()) {
scopeElement.addContent(scopeEl.clone());
}
} else {
scopes.put(scopeName, element.clone());
}
continue;
}
elements.add(element.clone());
}
return Boolean.parseBoolean(sourceElement.getAttributeValue("enabled"));
}
return false;
public String[] getSourceToolNames() {
return new String[] {"UNUSED_SYMBOL", "UnusedDeclaration"};
}
}
@@ -23,6 +23,7 @@ import com.intellij.packageDependencies.DependencyRule;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.FactoryMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,13 +67,19 @@ public class DependencyInspectionBase extends BaseJavaBatchLocalInspectionTool {
if (!validationManager.hasRules()) return null;
if (validationManager.getApplicableRules(file).length == 0) return null;
final List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
final FactoryMap<PsiFile, DependencyRule[]> violations = new FactoryMap<PsiFile, DependencyRule[]>() {
@Nullable
@Override
protected DependencyRule[] create(PsiFile dependencyFile) {
return validationManager.getViolatorDependencyRules(file, dependencyFile);
}
};
DependenciesBuilder.analyzeFileDependencies(file, new DependenciesBuilder.DependencyProcessor() {
@Override
public void process(PsiElement place, PsiElement dependency) {
PsiFile dependencyFile = dependency.getContainingFile();
if (dependencyFile != null && dependencyFile.isPhysical() && dependencyFile.getVirtualFile() != null) {
final DependencyRule[] rule = validationManager.getViolatorDependencyRules(file, dependencyFile);
for (DependencyRule dependencyRule : rule) {
for (DependencyRule dependencyRule : violations.get(dependencyFile)) {
problems.add(manager.createProblemDescriptor(place, InspectionsBundle
.message("inspection.dependency.violator.problem.descriptor", dependencyRule.getDisplayText()), isOnTheFly,
createEditDependencyFixes(dependencyRule),
@@ -64,7 +64,7 @@ public class JavaCoreApplicationEnvironment extends CoreApplicationEnvironment {
registerFileType(JavaClassFileType.INSTANCE, "class");
registerFileType(JavaFileType.INSTANCE, "java");
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess;rb");
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
addExplicitExtension(LanguageParserDefinitions.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextParserDefinition());
@@ -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.
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
public class JavaCoreProjectEnvironment extends CoreProjectEnvironment {
public class JavaCoreProjectEnvironment extends CoreProjectEnvironment {
private final JavaFileManager myFileManager;
private final PackageIndex myPackageIndex;
@@ -173,9 +173,10 @@ public class ClsParsingUtil {
return StringUtil.isJavaIdentifier(identifier) && !JavaLexer.isKeyword(identifier, level);
}
public static LanguageLevel getLanguageLevelByVersion(final int version) {
switch (version) {
public static LanguageLevel getLanguageLevelByVersion(int major) {
switch (major) {
case Opcodes.V1_1:
case 45: // other variant of 1.1
case Opcodes.V1_2:
case Opcodes.V1_3:
return LanguageLevel.JDK_1_3;
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.dataFlow.DataFlowInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.profile.Profile;
@@ -185,6 +186,107 @@ public class InspectionProfileTest extends LightIdeaTestCase {
assertElementsEqual(element, copy);
}
public void testMergeUnusedDeclarationAndUnusedSymbol() throws Exception {
//no specific settings
final Element element = JDOMUtil.loadDocument("<inspections version=\"1.0\" is_locked=\"false\">\n" +
" <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
" <option name=\"myLocal\" value=\"true\" />\n" +
"</inspections>").getRootElement();
InspectionProfileImpl profile = createProfile();
profile.setBaseProfile(new InspectionProfileImpl("foo"));
profile.readExternal(element);
ModifiableModel model = profile.getModifiableModel();
model.commit();
final Element copy = new Element("inspections");
profile.writeExternal(copy);
assertElementsEqual(element, copy);
//settings to merge
final Element unusedProfile = JDOMUtil.loadDocument("<inspections version=\"1.0\" is_locked=\"false\">\n" +
" <option name=\"myName\" value=\"" + PROFILE + "\" />\n" +
" <option name=\"myLocal\" value=\"true\" />\n" +
" <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
" <option name=\"FIELD\" value=\"true\" />\n" +
" <option name=\"METHOD\" value=\"true\" />\n" +
" <option name=\"CLASS\" value=\"true\" />\n" +
" <option name=\"PARAMETER\" value=\"true\" />\n" +
" <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
" </inspection_tool>\n" +
" <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
" </inspection_tool>\n" +
"</inspections>").getRootElement();
profile.readExternal(unusedProfile);
model = profile.getModifiableModel();
model.commit();
assertEquals("<profile version=\"1.0\" is_locked=\"false\">\n" +
" <option name=\"myName\" value=\"ToConvert\" />\n" +
" <option name=\"myLocal\" value=\"true\" />\n" +
" <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
" <option name=\"FIELD\" value=\"true\" />\n" +
" <option name=\"METHOD\" value=\"true\" />\n" +
" <option name=\"CLASS\" value=\"true\" />\n" +
" <option name=\"PARAMETER\" value=\"true\" />\n" +
" <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
" </inspection_tool>\n" +
" <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
" </inspection_tool>\n" +
"</profile>", serialize(profile));
//make them default
profile = createProfile();
profile.setBaseProfile(new InspectionProfileImpl("foo"));
profile.readExternal(unusedProfile);
model = profile.getModifiableModel();
InspectionToolWrapper toolWrapper = ((InspectionProfileImpl)model).getInspectionTool("unused", getProject());
UnusedDeclarationInspectionBase tool = (UnusedDeclarationInspectionBase)toolWrapper.getTool();
tool.ADD_NONJAVA_TO_ENTRIES = true;
UnusedSymbolLocalInspectionBase inspectionTool = tool.getSharedLocalInspectionTool();
inspectionTool.REPORT_PARAMETER_FOR_PUBLIC_METHODS = true;
model.commit();
String mergedText = "<profile version=\"1.0\" is_locked=\"false\">\n" +
" <option name=\"myName\" value=\"ToConvert\" />\n" +
" <option name=\"myLocal\" value=\"true\" />\n" +
" <inspection_tool class=\"UNUSED_SYMBOL\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"LOCAL_VARIABLE\" value=\"true\" />\n" +
" <option name=\"FIELD\" value=\"true\" />\n" +
" <option name=\"METHOD\" value=\"true\" />\n" +
" <option name=\"CLASS\" value=\"true\" />\n" +
" <option name=\"PARAMETER\" value=\"true\" />\n" +
" <option name=\"REPORT_PARAMETER_FOR_PUBLIC_METHODS\" value=\"false\" />\n" +
" </inspection_tool>\n" +
" <inspection_tool class=\"UnusedDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"false\">\n" +
" <option name=\"ADD_MAINS_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_APPLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_SERVLET_TO_ENTRIES\" value=\"true\" />\n" +
" <option name=\"ADD_NONJAVA_TO_ENTRIES\" value=\"false\" />\n" +
" </inspection_tool>\n" +
" <inspection_tool class=\"unusedMerged\" />\n" +
"</profile>";
assertEquals(mergedText, serialize(profile));
//check merged
Element mergedElement = JDOMUtil.loadDocument(mergedText).getRootElement();
profile = createProfile();
profile.setBaseProfile(new InspectionProfileImpl("foo"));
profile.readExternal(mergedElement);
model = profile.getModifiableModel();
model.commit();
Element copyMerged = new Element("profile");
profile.writeExternal(copyMerged);
assertElementsEqual(mergedElement, copyMerged);
}
public void testLockProfile() throws Exception {
final List<InspectionToolWrapper> list = new ArrayList<InspectionToolWrapper>();
list.add(createTool("foo", true));
@@ -39,6 +39,8 @@ import org.jetbrains.annotations.Nullable;
public interface HighlightInfoType {
@NonNls String UNUSED_SYMBOL_SHORT_NAME = "unused";
@NonNls String UNUSED_SYMBOL_DISPLAY_NAME = InspectionsBundle.message("inspection.dead.code.display.name");
@Deprecated
@NonNls String UNUSED_SYMBOL_ID = "UnusedDeclaration";
HighlightInfoType ERROR = new HighlightInfoTypeImpl(HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES);
HighlightInfoType WARNING = new HighlightInfoTypeImpl(HighlightSeverity.WARNING, CodeInsightColors.WARNINGS_ATTRIBUTES);
@@ -15,14 +15,94 @@
*/
package com.intellij.codeInspection.ex;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jdom.Element;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Merges multiple inspections settings {@link #getSourceToolNames()} into another one {@link #getMergedToolName()}
*/
public abstract class InspectionElementsMerger {
public static final ExtensionPointName<InspectionElementsMerger> EP_NAME = ExtensionPointName.create("com.intellij.inspectionElementsMerger");
public abstract String getNewToolName();
public abstract Element merge(Map<String, Element> elements);
public abstract String getMergedToolName();
protected abstract String[] getSourceToolNames();
/**
* marker node to prevent multiple merging. Is needed when inspection's settings are equal to default and are skipped in profile
*/
public static String getMergedMarkerName(String toolName) {
return toolName + "Merged";
}
public Element merge(Map<String, Element> inspectionElements) {
LinkedHashMap<String, Element> scopes = null;
List<Element> content = null;
boolean enabled = false;
String level = null;
for (String sourceId : getSourceToolNames()) {
final Element sourceElement = inspectionElements.get(sourceId);
if (sourceElement != null) {
if (content == null) {
content = new ArrayList<Element>();
scopes = new LinkedHashMap<String, Element>();
}
collectContent(sourceElement, content, scopes);
enabled |= Boolean.parseBoolean(sourceElement.getAttributeValue(ToolsImpl.ENABLED_ATTRIBUTE));
if (level == null) {
level = getLevel(sourceElement);
}
}
}
if (content != null && !content.isEmpty()) {
final Element toolElement = new Element(InspectionProfileImpl.INSPECTION_TOOL_TAG);
toolElement.setAttribute(InspectionProfileImpl.CLASS_TAG, getMergedToolName());
toolElement.setAttribute(ToolsImpl.ENABLED_ATTRIBUTE, String.valueOf(enabled));
if (level != null) {
toolElement.setAttribute(ToolsImpl.LEVEL_ATTRIBUTE, level);
}
toolElement.setAttribute(ToolsImpl.ENABLED_BY_DEFAULT_ATTRIBUTE, String.valueOf(enabled));
for (Element scopeEl : scopes.values()) {
toolElement.addContent(scopeEl);
}
for (Element element : content) {
toolElement.addContent(element);
}
return toolElement;
}
return null;
}
private static String getLevel(Element element) {
return element != null ? element.getAttributeValue(ToolsImpl.LEVEL_ATTRIBUTE) : HighlightSeverity.WARNING.getName();
}
protected static void collectContent(Element sourceElement, List<Element> options, Map<String, Element> scopes) {
if (sourceElement != null) {
for (Element element : sourceElement.getChildren()) {
if ("scope".equals(element.getName())) {
String scopeName = element.getAttributeValue("name");
if (scopes.containsKey(scopeName)) {
Element scopeElement = scopes.get(scopeName);
for (Element scopeEl : element.getChildren()) {
scopeElement.addContent(scopeEl.clone());
}
} else {
scopes.put(scopeName, element.clone());
}
continue;
}
options.add(element.clone());
}
}
}
}
@@ -99,6 +99,18 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
private boolean myModified = false;
private volatile boolean myInitialized;
private static Map<String, InspectionElementsMerger> ourMergers = null;
private static synchronized Map<String, InspectionElementsMerger> getMergers() {
if (ourMergers == null) {
ourMergers = new LinkedHashMap<String, InspectionElementsMerger>();
for (InspectionElementsMerger merger : Extensions.getExtensions(InspectionElementsMerger.EP_NAME)) {
ourMergers.put(merger.getMergedToolName(), merger);
}
}
return ourMergers;
}
InspectionProfileImpl(@NotNull InspectionProfileImpl inspectionProfile) {
super(inspectionProfile.getName());
@@ -264,18 +276,6 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
myDeinstalledInspectionsSettings.put(toolClassName, toolElement);
}
for (InspectionElementsMerger merger : Extensions.getExtensions(InspectionElementsMerger.EP_NAME)) {
final String newToolName = merger.getNewToolName();
final String mergedToolName = newToolName + "Merged";
if (!myDeinstalledInspectionsSettings.containsKey(mergedToolName)) {
final Element merged = merger.merge(myDeinstalledInspectionsSettings);
if (merged != null) {
myDeinstalledInspectionsSettings.put(newToolName, merged);
myDeinstalledInspectionsSettings.put(mergedToolName, new Element(INSPECTION_TOOL_TAG).setAttribute(CLASS_TAG, mergedToolName));
}
}
}
}
@NotNull
@@ -315,7 +315,10 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
for (final String toolName : diffMap.keySet()) {
if (!myLockedProfile && diffMap.get(toolName).booleanValue()) continue;
if (!myLockedProfile && diffMap.get(toolName).booleanValue()) {
markSettingsMerged(toolName, element);
continue;
}
final Element toolElement = myDeinstalledInspectionsSettings.get(toolName);
if (toolElement == null) {
final ToolsImpl toolList = myTools.get(toolName);
@@ -323,6 +326,9 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
final Element inspectionElement = new Element(INSPECTION_TOOL_TAG);
inspectionElement.setAttribute(CLASS_TAG, toolName);
toolList.writeExternal(inspectionElement);
if (areSettingsMerged(toolName, inspectionElement)) continue;
element.addContent(inspectionElement);
}
else {
@@ -332,6 +338,29 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
}
private void markSettingsMerged(String toolName, Element element) {
//add marker if already merged but result is now default (-> empty node)
final String mergedName = InspectionElementsMerger.getMergedMarkerName(toolName);
if (!myDeinstalledInspectionsSettings.containsKey(mergedName)) {
final InspectionElementsMerger merger = getMergers().get(toolName);
if (merger != null && merger.merge(myDeinstalledInspectionsSettings) != null) {
element.addContent(new Element(INSPECTION_TOOL_TAG).setAttribute(CLASS_TAG, mergedName));
}
}
}
private boolean areSettingsMerged(String toolName, Element inspectionElement) {
//skip merged settings as they could be restored from already provided data
final InspectionElementsMerger merger = getMergers().get(toolName);
if (merger != null) {
Element merge = merger.merge(myDeinstalledInspectionsSettings);
if (merge != null && JDOMUtil.areElementsEqual(merge, inspectionElement)) {
return true;
}
}
return false;
}
public void collectDependentInspections(@NotNull InspectionToolWrapper toolWrapper,
@NotNull Set<InspectionToolWrapper> dependentEntries,
Project project) {
@@ -550,15 +579,24 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
HighlightDisplayLevel level = myBaseProfile != null ? myBaseProfile.getErrorLevel(key, project) : toolWrapper.getDefaultLevel();
boolean enabled = myBaseProfile != null ? myBaseProfile.isToolEnabled(key) : toolWrapper.isEnabledByDefault();
final ToolsImpl toolsList = new ToolsImpl(toolWrapper, level, !myLockedProfile && enabled, enabled);
final Element element = myDeinstalledInspectionsSettings.remove(toolWrapper.getShortName());
if (element != null) {
try {
final Element element = myDeinstalledInspectionsSettings.remove(shortName);
try {
if (element != null) {
toolsList.readExternal(element, this, dependencies);
}
catch (InvalidDataException e) {
LOG.error("Can't read settings for " + toolWrapper, e);
else if (!myDeinstalledInspectionsSettings.containsKey(InspectionElementsMerger.getMergedMarkerName(shortName))) {
final InspectionElementsMerger merger = getMergers().get(shortName);
if (merger != null) {
final Element merged = merger.merge(myDeinstalledInspectionsSettings);
if (merged != null) {
toolsList.readExternal(merged, this, dependencies);
}
}
}
}
catch (InvalidDataException e) {
LOG.error("Can't read settings for " + toolWrapper, e);
}
myTools.put(toolWrapper.getShortName(), toolsList);
}
final GraphGenerator<String> graphGenerator = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<String>() {
@@ -49,7 +49,7 @@ import java.util.List;
import java.util.Map;
public class ToolsImpl implements Tools {
@NonNls private static final String ENABLED_BY_DEFAULT_ATTRIBUTE = "enabled_by_default";
@NonNls public static final String ENABLED_BY_DEFAULT_ATTRIBUTE = "enabled_by_default";
@NonNls public static final String ENABLED_ATTRIBUTE = "enabled";
@NonNls public static final String LEVEL_ATTRIBUTE = "level";
@@ -1,5 +1,6 @@
com.intellij.codeInspection.canBeFinal.CanBeFinalInspection
com.intellij.codeInspection.dataFlow.DataFlowInspection
com.intellij.codeInspection.deadCode.UnusedDeclarationInspection
com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection
com.intellij.codeInspection.defUse.DefUseInspection
com.intellij.codeInspection.duplicatePropertyInspection.DuplicatePropertyInspection
@@ -16,6 +17,7 @@ com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspect
com.intellij.codeInspection.nullable.NullableStuffInspection
com.intellij.codeInspection.suspiciousNameCombination.SuspiciousNameCombinationInspection
com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection
com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection
com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection
com.intellij.codeInspection.visibility.VisibilityInspection
com.intellij.lang.javascript.inspections.JSMismatchedCollectionQueryUpdateInspection
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 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,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.execution.process;
package com.intellij.openapi.execution;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -113,8 +113,13 @@ public abstract class ModuleType<T extends ModuleBuilder> {
}
public static ModuleType get(@NotNull Module module) {
ModuleTypeManager instance = ModuleTypeManager.getInstance();
return instance == null && ApplicationManager.getApplication().isUnitTestMode() ? EMPTY : instance.findByID(module.getOptionValue(Module.ELEMENT_TYPE));
try {
ModuleTypeManager instance = ModuleTypeManager.getInstance();
return instance == null && ApplicationManager.getApplication().isUnitTestMode() ? EMPTY : instance.findByID(module.getOptionValue(Module.ELEMENT_TYPE));
}
catch (Exception e) {
return EMPTY;
}
}
@NotNull
@@ -947,7 +947,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
final MouseEvent me = (MouseEvent)event;
if (SwingUtilities.isDescendingFrom(me.getComponent(), SwingUtilities.getWindowAncestor(myContentWrapper)) || isPopupOverEditor(me.getComponent())) {
queueModificationCheck();
myFilter.setHoldingFilter(false);
}
}
else if (event.getID() == KeyEvent.KEY_PRESSED || event.getID() == KeyEvent.KEY_RELEASED) {
@@ -33,10 +33,12 @@ import com.intellij.openapi.editor.markup.HighlighterTargetArea;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.Processor;
import com.intellij.util.text.CharSequenceSubSequence;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -47,8 +49,6 @@ import java.awt.*;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author gregsh
@@ -134,9 +134,6 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer,
}
private static class MyPanel extends CellRendererPanel implements Disposable {
private static final String LINE_TERMINATOR_PATTERN_TEXT = "\\n|(?:\\r\\n?)|\\u0085|\\u2028|\\u2029";
private static final Pattern LINE_TERMINATOR_OR_A_CHARACTER_PATTERN = Pattern.compile("(" + LINE_TERMINATOR_PATTERN_TEXT + ")|.");
private static final Pattern LINE_PATTERN = Pattern.compile("(.*)(" + LINE_TERMINATOR_PATTERN_TEXT + ")?");
private static final char ABBREVIATION_SUFFIX = '\u2026'; // 2026 '...'
private static final char RETURN_SYMBOL = '\u23ce';
@@ -189,9 +186,8 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer,
int maxLineLength = 0;
int linesCount = 0;
Matcher m = LINE_PATTERN.matcher(myRawText);
while (m.find()) {
maxLineLength = Math.max(maxLineLength, m.end(1) - m.start());
for (LineTokenizer lt = new LineTokenizer(myRawText); !lt.atEnd(); lt.advance()) {
maxLineLength = Math.max(maxLineLength, lt.getLength());
linesCount++;
}
@@ -219,11 +215,10 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer,
appendAbbreviated(myDocumentTextBuilder, myRawText, 0, myRawText.length(), fontMetrics, maxLineWidth, true);
}
else {
Matcher m = LINE_PATTERN.matcher(myRawText);
int visibleLinesCount = (int)Math.floor(visibleLinesCountFractional + 0.5);
for (int i = 0; i < visibleLinesCount && m.find(); i++) {
appendAbbreviated(myDocumentTextBuilder, myRawText, m.start(1), m.end(1), fontMetrics, maxLineWidth, false);
if (m.start(2) != -1) {
int linesToAppend = (int)Math.floor(visibleLinesCountFractional + 0.5);
for (LineTokenizer lt = new LineTokenizer(myRawText); !lt.atEnd() && linesToAppend > 0; lt.advance(), linesToAppend--) {
appendAbbreviated(myDocumentTextBuilder, myRawText, lt.getOffset(), lt.getOffset() + lt.getLength(), fontMetrics, maxLineWidth, false);
if (lt.getLineSeparatorLength() > 0) {
myDocumentTextBuilder.append('\n');
}
}
@@ -249,51 +244,47 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer,
private static void appendAbbreviated(StringBuilder to, String text, int start, int end,
FontMetrics metrics, int maxWidth, boolean replaceLineTerminators) {
if (metrics.charWidth('m') * (end - start) <= maxWidth) {
appendAndReplaceLineTerminatorsIfNeeded(to, text, start, end, replaceLineTerminators);
return;
int abbreviationLength = abbreviationLength(text, start, end, metrics, maxWidth, replaceLineTerminators);
if (!replaceLineTerminators) {
to.append(text, start, start + abbreviationLength);
}
int abbrWidth = metrics.charWidth(ABBREVIATION_SUFFIX);
int abbrIdx = start;
Matcher m = LINE_TERMINATOR_OR_A_CHARACTER_PATTERN.matcher(text);
m.region(start, end);
while (m.find()) {
int appendWidth = 0;
if (replaceLineTerminators && m.start(1) != -1) {
appendWidth = metrics.charWidth(RETURN_SYMBOL);
}
else {
for (int i = m.start(); i < m.end(); i++) {
appendWidth += metrics.charWidth(text.charAt(i));
}
}
if (abbrWidth + appendWidth >= maxWidth) break;
abbrWidth += appendWidth;
abbrIdx = m.end();
}
appendAndReplaceLineTerminatorsIfNeeded(to, text, start, abbrIdx, replaceLineTerminators);
to.append(ABBREVIATION_SUFFIX);
}
private static void appendAndReplaceLineTerminatorsIfNeeded(StringBuilder to, String text, int start, int end, boolean doReplace) {
if (doReplace) {
Matcher m = LINE_PATTERN.matcher(text);
m.region(start, end);
while (m.find()) {
to.append(text, m.start(1), m.end(1));
if (m.start(2) != -1) {
else {
CharSequenceSubSequence subSeq = new CharSequenceSubSequence(text, start, start + abbreviationLength);
for (LineTokenizer lt = new LineTokenizer(subSeq); !lt.atEnd(); lt.advance()) {
to.append(subSeq, lt.getOffset(), lt.getOffset() + lt.getLength());
if (lt.getLineSeparatorLength() > 0) {
to.append(RETURN_SYMBOL);
}
}
}
else {
to.append(text, start, end);
if (abbreviationLength != end - start) {
to.append(ABBREVIATION_SUFFIX);
}
}
private static int abbreviationLength(String text, int start, int end, FontMetrics metrics, int maxWidth, boolean replaceSeparators) {
if (metrics.charWidth('m') * (end - start) <= maxWidth) return end - start;
int abbrWidth = metrics.charWidth(ABBREVIATION_SUFFIX);
int abbrLength = 0;
CharSequenceSubSequence subSeq = new CharSequenceSubSequence(text, start, end);
for (LineTokenizer lt = new LineTokenizer(subSeq); !lt.atEnd(); lt.advance()) {
for (int i = 0; i < lt.getLength(); i++, abbrLength++) {
abbrWidth += metrics.charWidth(subSeq.charAt(lt.getOffset() + i));
if (abbrWidth >= maxWidth) return abbrLength;
}
if (replaceSeparators && lt.getLineSeparatorLength() != 0) {
abbrWidth += metrics.charWidth(RETURN_SYMBOL);
if (abbrWidth >= maxWidth) return abbrLength;
abbrLength += lt.getLineSeparatorLength();
}
}
return abbrLength;
}
}
private static class MyDocument extends UserDataHolderBase implements DocumentEx {
@@ -56,7 +56,7 @@ xdebugger.button.evaluate=E&valuate
xdebugger.evaluate.dialog.close=Close
xdebugger.dialog.title.evaluate.expression=Evaluate Expression
xdebugger.evaluate.label.expression=Expression:
xdebugger.evaluate.addtowatches.hint=Use Control+Enter to add to Watches
xdebugger.evaluate.addtowatches.hint=Use Alt+Enter to add to Watches
dialog.title.evaluate.code.fragment=Evaluate Code Fragment
button.text.code.fragment.mode=Code Fragment &Mode
button.text.expression.mode=Expression &Mode
@@ -108,6 +108,21 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
mySwitchModeAction = new SwitchModeAction();
new AnAction(){
@Override
public void actionPerformed(AnActionEvent e) {
doOKAction();
}
}.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK)), getRootPane(), myDisposable);
new AnAction(){
@Override
public void actionPerformed(AnActionEvent e) {
doOKAction();
addToWatches();
}
}.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_DOWN_MASK)), getRootPane(), myDisposable);
new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
@@ -128,9 +143,6 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
if (mode == EvaluationMode.CODE_FRAGMENT && !myIsCodeFragmentEvaluationSupported) {
mode = EvaluationMode.EXPRESSION;
}
if (mode == EvaluationMode.EXPRESSION) {
text = new XExpressionImpl(StringUtil.replace(text.getExpression(), "\n", " "), text.getLanguage(), text.getCustomInfo());
}
switchToMode(mode, text);
init();
}
@@ -157,21 +169,26 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
if (myMode == EvaluationMode.EXPRESSION && ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
// add to watches
XExpression expression = getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
if (tab != null) {
tab.getWatchesView().addWatchExpression(expression, -1, true);
requestFocusInEditor();
}
}
if (((e.getModifiers() & InputEvent.ALT_MASK) != 0)) {
addToWatches();
}
}
};
}
private void addToWatches() {
if (myMode == EvaluationMode.EXPRESSION) {
XExpression expression = getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
if (tab != null) {
tab.getWatchesView().addWatchExpression(expression, -1, true);
requestFocusInEditor();
}
}
}
}
@NotNull
@Override
protected Action[] createActions() {
@@ -216,6 +233,10 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
myMode = mode;
if (mode == EvaluationMode.EXPRESSION) {
text = new XExpressionImpl(StringUtil.replace(text.getExpression(), "\n", " "), text.getLanguage(), text.getCustomInfo());
}
myInputComponent = createInputComponent(mode, text);
myMainPanel.removeAll();
myInputComponent.addComponent(myMainPanel, myResultPanel);
@@ -313,7 +334,6 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
switchToMode(EvaluationMode.CODE_FRAGMENT, text);
}
else {
if (text.getExpression().indexOf('\n') != -1) text = XExpressionImpl.EMPTY_EXPRESSION;
switchToMode(EvaluationMode.EXPRESSION, text);
}
}
@@ -99,31 +99,31 @@ public class ClassWriter {
DecompilerContext.getLogger().startWriteClass(node.simpleName);
if (node.lambda_information.is_method_reference) {
if (!node.lambda_information.is_content_method_static && method_object != null) {
if (node.lambdaInformation.is_method_reference) {
if (!node.lambdaInformation.is_content_method_static && method_object != null) {
// reference to a virtual method
buffer.append(method_object.toJava(indent, tracer));
}
else {
// reference to a static method
buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambda_information.content_class_name, false)));
buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, false)));
}
buffer.append("::");
buffer.append(node.lambda_information.content_method_name);
buffer.append(node.lambdaInformation.content_method_name);
}
else {
// lambda method
StructMethod mt = cl.getMethod(node.lambda_information.content_method_key);
StructMethod mt = cl.getMethod(node.lambdaInformation.content_method_key);
MethodWrapper methodWrapper = wrapper.getMethodWrapper(mt.getName(), mt.getDescriptor());
MethodDescriptor md_content = MethodDescriptor.parseDescriptor(node.lambda_information.content_method_descriptor);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambda_information.method_descriptor);
MethodDescriptor md_content = MethodDescriptor.parseDescriptor(node.lambdaInformation.content_method_descriptor);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(node.lambdaInformation.method_descriptor);
if (!lambdaToAnonymous) {
buffer.append('(');
boolean firstParameter = true;
int index = node.lambda_information.is_content_method_static ? 0 : 1;
int index = node.lambdaInformation.is_content_method_static ? 0 : 1;
int start_index = md_content.params.length - md_lambda.params.length;
for (int i = 0; i < md_content.params.length; i++) {
@@ -250,7 +250,7 @@ public class ClassWriter {
for (ClassNode inner : node.nested) {
if (inner.type == ClassNode.CLASS_MEMBER) {
StructClass innerCl = inner.classStruct;
boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic();
boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic() || inner.namelessConstructorStub;
boolean hide = isSynthetic && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
wrapper.getHiddenMembers().contains(innerCl.qualifiedName);
if (hide) continue;
@@ -485,9 +485,9 @@ public class ClassWriter {
DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_WRAPPER, methodWrapper);
try {
String method_name = lambdaNode.lambda_information.method_name;
MethodDescriptor md_content = MethodDescriptor.parseDescriptor(lambdaNode.lambda_information.content_method_descriptor);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(lambdaNode.lambda_information.method_descriptor);
String method_name = lambdaNode.lambdaInformation.method_name;
MethodDescriptor md_content = MethodDescriptor.parseDescriptor(lambdaNode.lambdaInformation.content_method_descriptor);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(lambdaNode.lambdaInformation.method_descriptor);
if (!codeOnly) {
buffer.appendIndent(indent);
@@ -496,7 +496,7 @@ public class ClassWriter {
buffer.append("(");
boolean firstParameter = true;
int index = lambdaNode.lambda_information.is_content_method_static ? 0 : 1;
int index = lambdaNode.lambdaInformation.is_content_method_static ? 0 : 1;
int start_index = md_content.params.length - md_lambda.params.length;
for (int i = 0; i < md_content.params.length; i++) {
@@ -347,30 +347,19 @@ public class ClassesProcessor {
public static final int CLASS_LAMBDA = 8;
public int type;
public int access;
public String simpleName;
public StructClass classStruct;
public ClassWrapper wrapper;
public String enclosingMethod;
public InvocationExprent superInvocation;
public HashMap<String, VarVersionPaar> mapFieldsToVars = new HashMap<String, VarVersionPaar>();
public Map<String, VarVersionPaar> mapFieldsToVars = new HashMap<String, VarVersionPaar>();
public VarType anonymousClassType;
public List<ClassNode> nested = new ArrayList<ClassNode>();
public Set<String> enclosingClasses = new HashSet<String>();
public ClassNode parent;
public LambdaInformation lambda_information;
public LambdaInformation lambdaInformation;
public boolean namelessConstructorStub = false;
public ClassNode(String content_class_name,
String content_method_name,
@@ -383,19 +372,19 @@ public class ClassesProcessor {
this.type = CLASS_LAMBDA;
this.classStruct = classStruct; // 'parent' class containing the static function
lambda_information = new LambdaInformation();
lambdaInformation = new LambdaInformation();
lambda_information.class_name = lambda_class_name;
lambda_information.method_name = lambda_method_name;
lambda_information.method_descriptor = lambda_method_descriptor;
lambdaInformation.class_name = lambda_class_name;
lambdaInformation.method_name = lambda_method_name;
lambdaInformation.method_descriptor = lambda_method_descriptor;
lambda_information.content_class_name = content_class_name;
lambda_information.content_method_name = content_method_name;
lambda_information.content_method_descriptor = content_method_descriptor;
lambda_information.content_method_invocation_type = content_method_invocation_type;
lambdaInformation.content_class_name = content_class_name;
lambdaInformation.content_method_name = content_method_name;
lambdaInformation.content_method_descriptor = content_method_descriptor;
lambdaInformation.content_method_invocation_type = content_method_invocation_type;
lambda_information.content_method_key =
InterpreterUtil.makeUniqueKey(lambda_information.content_method_name, lambda_information.content_method_descriptor);
lambdaInformation.content_method_key =
InterpreterUtil.makeUniqueKey(lambdaInformation.content_method_name, lambdaInformation.content_method_descriptor);
anonymousClassType = new VarType(lambda_class_name, true);
@@ -405,9 +394,9 @@ public class ClassesProcessor {
is_method_reference = !mt.isSynthetic(); // if not synthetic -> method reference
}
lambda_information.is_method_reference = is_method_reference;
lambda_information.is_content_method_static =
(lambda_information.content_method_invocation_type == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic); // FIXME: redundant?
lambdaInformation.is_method_reference = is_method_reference;
lambdaInformation.is_content_method_static =
(lambdaInformation.content_method_invocation_type == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic); // FIXME: redundant?
}
public ClassNode(int type, StructClass classStruct) {
@@ -435,7 +424,6 @@ public class ClassesProcessor {
public String content_method_name;
public String content_method_descriptor;
public int content_method_invocation_type; // values from CONSTANT_MethodHandle_REF_*
public String content_method_key;
public boolean is_method_reference;
@@ -39,56 +39,72 @@ public class PrintStreamLogger extends IFernflowerLogger {
@Override
public void writeMessage(String message, Throwable t) {
writeMessage(message, Severity.ERROR);
if (accepts(Severity.ERROR)) {
writeMessage(message, Severity.ERROR);
t.printStackTrace(stream);
}
}
@Override
public void startReadingClass(String className) {
writeMessage("Decompiling class " + className, Severity.INFO);
++indent;
if (accepts(Severity.INFO)) {
writeMessage("Decompiling class " + className, Severity.INFO);
++indent;
}
}
@Override
public void endReadingClass() {
--indent;
writeMessage("... done", Severity.INFO);
if (accepts(Severity.INFO)) {
--indent;
writeMessage("... done", Severity.INFO);
}
}
@Override
public void startClass(String className) {
writeMessage("Processing class " + className, Severity.TRACE);
++indent;
if (accepts(Severity.INFO)) {
writeMessage("Processing class " + className, Severity.TRACE);
++indent;
}
}
@Override
public void endClass() {
--indent;
writeMessage("... proceeded", Severity.TRACE);
if (accepts(Severity.INFO)) {
--indent;
writeMessage("... proceeded", Severity.TRACE);
}
}
@Override
public void startMethod(String methodName) {
writeMessage("Processing method " + methodName, Severity.TRACE);
++indent;
if (accepts(Severity.INFO)) {
writeMessage("Processing method " + methodName, Severity.TRACE);
++indent;
}
}
public void endMethod() {
--indent;
writeMessage("... proceeded", Severity.TRACE);
if (accepts(Severity.INFO)) {
--indent;
writeMessage("... proceeded", Severity.TRACE);
}
}
@Override
public void startWriteClass(String className) {
writeMessage("Writing class " + className, Severity.TRACE);
++indent;
if (accepts(Severity.INFO)) {
writeMessage("Writing class " + className, Severity.TRACE);
++indent;
}
}
@Override
public void endWriteClass() {
--indent;
writeMessage("... written", Severity.TRACE);
if (accepts(Severity.INFO)) {
--indent;
writeMessage("... written", Severity.TRACE);
}
}
}
@@ -122,7 +122,7 @@ public class LambdaProcessor {
node_lambda.parent = node;
clprocessor.getMapRootClasses().put(node_lambda.simpleName, node_lambda);
mapMethodsLambda.put(node_lambda.lambda_information.content_method_key, node_lambda.simpleName);
mapMethodsLambda.put(node_lambda.lambdaInformation.content_method_key, node_lambda.simpleName);
}
}
}
@@ -47,10 +47,10 @@ public class NestedClassProcessor {
public void processClass(ClassNode root, ClassNode node) {
// hide synthetic lambda content methods
if (node.type == ClassNode.CLASS_LAMBDA && !node.lambda_information.is_method_reference) {
if (node.type == ClassNode.CLASS_LAMBDA && !node.lambdaInformation.is_method_reference) {
ClassNode node_content = DecompilerContext.getClassProcessor().getMapRootClasses().get(node.classStruct.qualifiedName);
if (node_content != null && node_content.wrapper != null) {
node_content.wrapper.getHiddenMembers().add(node.lambda_information.content_method_key);
node_content.wrapper.getHiddenMembers().add(node.lambdaInformation.content_method_key);
}
}
@@ -75,10 +75,11 @@ public class NestedClassProcessor {
child.simpleName = "SyntheticClass_" + (++synthetics);
}
else {
DecompilerContext.getLogger().writeMessage("Nameless local or member class " + cl.qualifiedName + "!",
IFernflowerLogger.Severity.WARN);
String message = "Nameless local or member class " + cl.qualifiedName + "!";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN);
child.simpleName = "NamelessClass_" + (++nameless);
}
child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0;
}
}
@@ -86,13 +87,11 @@ public class NestedClassProcessor {
if (child.type == ClassNode.CLASS_LAMBDA) {
setLambdaVars(node, child);
}
else {
if (child.type != ClassNode.CLASS_MEMBER || (child.access & CodeConstants.ACC_STATIC) == 0) {
insertLocalVars(node, child);
else if (child.type != ClassNode.CLASS_MEMBER || (child.access & CodeConstants.ACC_STATIC) == 0) {
insertLocalVars(node, child);
if (child.type == ClassNode.CLASS_LOCAL) {
setLocalClassDefinition(node.wrapper.getMethods().getWithKey(child.enclosingMethod), child);
}
if (child.type == ClassNode.CLASS_LOCAL) {
setLocalClassDefinition(node.wrapper.getMethods().getWithKey(child.enclosingMethod), child);
}
}
}
@@ -104,22 +103,22 @@ public class NestedClassProcessor {
private static void setLambdaVars(ClassNode parent, ClassNode child) {
if (child.lambda_information.is_method_reference) { // method reference, no code and no parameters
if (child.lambdaInformation.is_method_reference) { // method reference, no code and no parameters
return;
}
final MethodWrapper meth = parent.wrapper.getMethods().getWithKey(child.lambda_information.content_method_key);
final MethodWrapper meth = parent.wrapper.getMethods().getWithKey(child.lambdaInformation.content_method_key);
final MethodWrapper encmeth = parent.wrapper.getMethods().getWithKey(child.enclosingMethod);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(child.lambda_information.method_descriptor);
final MethodDescriptor md_content = MethodDescriptor.parseDescriptor(child.lambda_information.content_method_descriptor);
MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(child.lambdaInformation.method_descriptor);
final MethodDescriptor md_content = MethodDescriptor.parseDescriptor(child.lambdaInformation.content_method_descriptor);
final int vars_count = md_content.params.length - md_lambda.params.length;
// if(vars_count < 0) { // should not happen, but just in case...
// vars_count = 0;
// }
final boolean is_static_lambda_content = child.lambda_information.is_content_method_static;
final boolean is_static_lambda_content = child.lambdaInformation.is_content_method_static;
final String parent_class_name = parent.wrapper.getClassStruct().qualifiedName;
final String lambda_class_name = child.simpleName;
@@ -311,20 +311,31 @@ public class NewExprent extends Exprent {
if (!enumconst || start < lstParameters.size()) {
buf.append("(");
boolean firstpar = true;
boolean firstParam = true;
for (int i = start; i < lstParameters.size(); i++) {
if (sigFields == null || sigFields.get(i) == null) {
if (!firstpar) {
Exprent expr = lstParameters.get(i);
VarType leftType = constructor.getDescriptor().params[i];
if (i == lstParameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) {
ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(leftType.value);
if (node != null && node.namelessConstructorStub) {
break; // skip last parameter of synthetic constructor call
}
}
if (!firstParam) {
buf.append(", ");
}
TextBuffer buff = new TextBuffer();
ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buff, indent, true, tracer);
ExprProcessor.getCastedExprent(expr, leftType, buff, indent, true, tracer);
buf.append(buff);
firstpar = false;
firstParam = false;
}
}
buf.append(")");
}
}
@@ -34,4 +34,6 @@ public class SingleClassesTest extends SingleClassesTestBase {
@Test public void testEnum() { doTest("pkg/TestEnum"); }
@Test public void testDebugSymbols() { doTest("pkg/TestDebugSymbols"); }
@Test public void testInvalidMethodSignature() { doTest("InvalidMethodSignature"); }
@Test public void testInnerClassConstructor() { doTest("pkg/TestInnerClassConstructor"); }
@Test public void testInnerClassConstructor11() { doTest("v11/TestInnerClassConstructor"); }
}
@@ -0,0 +1,17 @@
package pkg;
class TestInnerClassConstructor {
void m() {
new TestInnerClassConstructor.Inner("text");
}
void n(String var1) {
System.out.println("n(): " + var1);
}
final class Inner {
private Inner(String var2) {
TestInnerClassConstructor.this.n(var2);
}
}
}
@@ -0,0 +1,17 @@
package pkg;
class TestInnerClassConstructor {
void m() {
new Inner("text");
}
void n(String s) {
System.out.println("n(): " + s);
}
final class Inner {
private Inner(String s) {
n(s);
}
}
}
+1 -1
View File
@@ -833,7 +833,7 @@ class PyDB:
# the id to be the line.
breakpoint_id = line = int(line)
if condition.startswith('**FUNC**'):
func_name, condition = condition.split('\t', 1)
func_name, condition = condition.split("@_@TAB_CHAR@_@", 1)
# We must restore new lines and tabs as done in
# AbstractDebugTarget.breakpointAdded
@@ -51,6 +51,7 @@ public abstract class AbstractCommand<T> {
public static final int VERSION = 501;
public static final String NEW_LINE_CHAR = "@_@NEW_LINE_CHAR@_@";
public static final String TAB_CHAR = "@_@TAB_CHAR@_@";
public static final String FUNC_IN_CONDITION = "**FUNC**";
@NotNull private final RemoteDebugger myDebugger;
@@ -7,14 +7,16 @@ import org.jetbrains.annotations.Nullable;
public class SetBreakpointCommand extends LineBreakpointCommand {
private @Nullable final String myCondition;
private @Nullable final String myLogExpression;
private @Nullable final String myFuncName;
public SetBreakpointCommand(@NotNull final RemoteDebugger debugger,
@NotNull final String type,
@NotNull final String file,
@NotNull final int line) {
this(debugger, type, file, line, null, null);
this(debugger, type, file, line, null, null, null);
}
public SetBreakpointCommand(@NotNull final RemoteDebugger debugger,
@NotNull final String type,
@NotNull final String file,
@@ -24,12 +26,46 @@ public class SetBreakpointCommand extends LineBreakpointCommand {
super(debugger, type, SET_BREAKPOINT, file, line);
myCondition = condition;
myLogExpression = logExpression;
myFuncName = null;
}
public SetBreakpointCommand(@NotNull final RemoteDebugger debugger,
@NotNull final String type,
@NotNull final String file,
@NotNull final int line,
@Nullable final String condition,
@Nullable final String logExpression,
@Nullable final String funcName) {
super(debugger, type, SET_BREAKPOINT, file, line);
myCondition = condition;
myLogExpression = logExpression;
myFuncName = funcName;
}
@Override
protected void buildPayload(Payload payload) {
super.buildPayload(payload);
payload.add(buildCondition(myCondition)).add(buildCondition(myLogExpression));
payload.add(buildConditionWithFunc(myCondition, myFuncName)).add(buildCondition(myLogExpression));
}
@NotNull
private static String buildConditionWithFunc(String expression, String functionName) {
StringBuilder builder = new StringBuilder();
if (functionName != null) {
builder.append(FUNC_IN_CONDITION);
builder.append(functionName);
builder.append(TAB_CHAR);
}
if (expression != null) {
builder.append(expression.replaceAll("\n", NEW_LINE_CHAR));
} else {
builder.append("None");
}
String condition = builder.toString();
return condition.replaceAll("\t", TAB_CHAR);
}
@NotNull
@@ -28,7 +28,6 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.console.ConsoleHistoryController;
import com.intellij.execution.console.LanguageConsoleView;
import com.intellij.execution.console.ProcessBackedConsoleExecuteActionHandler;
import com.intellij.execution.process.CommandLineArgumentsProvider;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessOutputTypes;
@@ -46,6 +45,7 @@ import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.editor.actions.SplitLineAction;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.execution.CommandLineArgumentsProvider;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 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.
@@ -16,26 +16,22 @@
package com.jetbrains.python.run;
import com.google.common.collect.Lists;
import com.intellij.execution.*;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.process.CommandLineArgumentsProvider;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.execution.CommandLineArgumentsProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.UIUtil;
import com.jetbrains.python.PythonHelpersLocator;
import com.jetbrains.python.console.PyConsoleType;
import com.jetbrains.python.console.PydevConsoleRunner;
@@ -43,7 +39,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -48,6 +48,7 @@ builtin
bzip
calc
callee
camelcase
cancelable
cancellable
capath
@@ -76,6 +77,8 @@ codesign
commandline
committer
commonjs
concat
cond
conf
config
configs
@@ -131,11 +134,14 @@ endregion
enqueue
enum
enums
eqeqeq
eval
evex
exif
expr
facebook
facelet
fallthrough
favicon
filename
fileset
@@ -189,6 +195,7 @@ html
http
https
iconable
iife
impl
inbox
incrementer
@@ -207,6 +214,7 @@ insteadof
intellij
iphone
iphoneos
isnan
isnull
javabean
javabeans
@@ -225,6 +233,7 @@ jnilib
jpeg
jpdl
jquery
jsdoc
jsessionid
jshint
json
@@ -357,6 +366,7 @@ pageable
param
parameterizable
params
paren
patcher
patchers
pathname
@@ -374,6 +384,7 @@ plist
plsql
plugin
plugins
plusplus
pointcut
pointcuts
portlet
@@ -397,6 +408,7 @@ println
processlist
profiler
progressbar
proto
proven
proxool
pycharm
@@ -408,6 +420,7 @@ rebase
rebased
rebasing
rect
redeclare
redis
redispatch
redistributions
@@ -562,10 +575,13 @@ tuple
twitter
typedef
typedefs
typeof
unary
unboxing
unbuffered
uncomment
uncommented
undef
underwave
undoable
undofile