diff --git a/build/order.txt b/build/order.txt index dc0069234894..9fdc720edae0 100644 --- a/build/order.txt +++ b/build/order.txt @@ -10602,6 +10602,7 @@ gutter/overridingMethod.png:/lib/icons.jar gutter/implementingMethod.png:/lib/icons.jar gutter/overridenMethod.png:/lib/icons.jar gutter/implementedMethod.png:/lib/icons.jar +gutter/recursiveMethod.png:/lib/icons.jar com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl$1.class:/lib/idea.jar com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider.class:/lib/idea.jar com/intellij/codeInsight/daemon/impl/IconLineMarkerProvider$1.class:/lib/idea.jar diff --git a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java index 519e55bd9cf9..7ac97854bead 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java @@ -643,7 +643,8 @@ public class CompileServerManager implements ApplicationComponent{ cmdLine.addParameter("-classpath"); - final List cp = ClasspathBootstrap.getCompileServerApplicationClasspath(); + final List cp = ClasspathBootstrap.getBuildProcessApplicationClasspath(); + cp.add(ClasspathBootstrap.getResourcePath(systemCompiler.getClass())); // tools.jar cp.addAll(myClasspathManager.getCompileServerPluginsClasspath()); cmdLine.addParameter(classpathToString(cp)); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 00206e02133a..694e701848f5 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -565,14 +565,10 @@ public class BuildManager implements ApplicationComponent{ } private Process launchBuildProcess(Project project, final int port, final UUID sessionId) throws ExecutionException { - // validate tools.jar presence - final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); - if (systemCompiler == null) { - throw new ExecutionException("No system java compiler is provided by the JRE. Make sure tools.jar is present in IntelliJ IDEA classpath."); - } // choosing sdk with which the build process should be run - Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); + final Sdk internalJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); + Sdk projectJdk = internalJdk; final String versionString = projectJdk.getVersionString(); if (versionString != null) { JavaSdkVersion sdkVersion = ((JavaSdk)projectJdk.getSdkType()).getVersion(versionString); @@ -600,6 +596,23 @@ public class BuildManager implements ApplicationComponent{ } } + // validate tools.jar presence + final File compilerPath; + if (projectJdk.equals(internalJdk)) { + final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); + if (systemCompiler == null) { + throw new ExecutionException("No system java compiler is provided by the JRE. Make sure tools.jar is present in IntelliJ IDEA classpath."); + } + compilerPath = ClasspathBootstrap.getResourcePath(systemCompiler.getClass()); + } + else { + final String path = ((JavaSdk)projectJdk.getSdkType()).getToolsPath(projectJdk); + if (path == null) { + throw new ExecutionException("Cannot determine path to 'tools.jar' library for " + projectJdk.getName() + " (" + projectJdk.getHomePath() + ")"); + } + compilerPath = new File(path); + } + final GeneralCommandLine cmdLine = new GeneralCommandLine(); final String vmExecutablePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk); cmdLine.setExePath(vmExecutablePath); @@ -667,7 +680,8 @@ public class BuildManager implements ApplicationComponent{ cmdLine.addParameter("-classpath"); - final List cp = ClasspathBootstrap.getCompileServerApplicationClasspath(); + final List cp = ClasspathBootstrap.getBuildProcessApplicationClasspath(); + cp.add(compilerPath); cp.addAll(myClasspathManager.getCompileServerPluginsClasspath()); cmdLine.addParameter(classpathToString(cp)); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java index 4a26b2c25866..df86eee27b19 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java @@ -32,6 +32,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.search.searches.AllOverridingMethodsSearch; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -60,6 +61,8 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { private static final Icon IMPLEMENTED_INTERFACE_MARKER_RENDERER = IMPLEMENTED_METHOD_MARKER_RENDERER; private static final Icon SUBCLASSED_CLASS_MARKER_RENDERER = OVERRIDEN_METHOD_MARKER_RENDERER; + private static final Icon RECURSIVE_METHOD_ICON = IconLoader.getIcon("/gutter/recursiveMethod.png"); + protected final DaemonCodeAnalyzerSettings myDaemonSettings; protected final EditorColorsManager myColorsManager; @@ -164,6 +167,11 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { } else if (element instanceof PsiClass && !(element instanceof PsiTypeParameter)) { collectInheritingClasses((PsiClass)element, result); + } else if(element instanceof PsiMethodCallExpression){ + final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element; + if (isRecursiveMethodCall(methodCall)){ + result.add(new RecursiveMethodCallMarkerInfo(methodCall)); + } } } if (!methods.isEmpty()) { @@ -171,6 +179,16 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { } } + private static boolean isRecursiveMethodCall(@NotNull PsiMethodCallExpression methodCall){ + final PsiMethod referencedMethod = (PsiMethod)methodCall.getMethodExpression().resolve(); + + if (referencedMethod == null){ + return false; + } + + return referencedMethod.getTextRange().contains(methodCall.getTextRange()); + } + private static void collectInheritingClasses(PsiClass aClass, Collection result) { if (aClass.hasModifierProperty(PsiModifier.FINAL)) { return; @@ -276,4 +294,36 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { }; } } + + private static class RecursiveMethodCallMarkerInfo extends MergeableLineMarkerInfo { + private RecursiveMethodCallMarkerInfo(@NotNull PsiMethodCallExpression methodCall) { + super(methodCall, + methodCall.getTextRange(), + RECURSIVE_METHOD_ICON, + Pass.UPDATE_OVERRIDEN_MARKERS, + FunctionUtil.constant("Recursive call"), + null, + GutterIconRenderer.Alignment.RIGHT + ); + } + + @Override + public boolean canMergeWith(@NotNull MergeableLineMarkerInfo info) { + if (!(info instanceof RecursiveMethodCallMarkerInfo)) return false; + PsiElement otherElement = info.getElement(); + PsiElement myElement = getElement(); + return otherElement != null && myElement != null; + } + + + @Override + public Icon getCommonIcon(@NotNull List infos) { + return myIcon; + } + + @Override + public Function getCommonTooltip(@NotNull List infos) { + return FunctionUtil.constant("Multiple recursive calls"); + } + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 423decc28335..fc1b17756ee8 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -168,11 +168,12 @@ final class BuildSession implements Runnable, CanceledStatus { final Project project = loadProject(projectPath); final File dataStorageRoot = Utils.getDataStorageRoot(project); + final boolean inMemoryMappingsDelta = System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null; ProjectTimestamps projectTimestamps = null; BuildDataManager dataManager = null; try { projectTimestamps = new ProjectTimestamps(dataStorageRoot); - dataManager = new BuildDataManager(dataStorageRoot, true); + dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); if (dataManager.versionDiffers()) { forceCleanCaches = true; msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required")); @@ -190,7 +191,7 @@ final class BuildSession implements Runnable, CanceledStatus { forceCleanCaches = true; FileUtil.delete(dataStorageRoot); projectTimestamps = new ProjectTimestamps(dataStorageRoot); - dataManager = new BuildDataManager(dataStorageRoot, true); + dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta); // second attempt succeded msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage())); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index 1279c09b17b2..59627572644e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -86,7 +86,7 @@ public class ClasspathBootstrap { private ClasspathBootstrap() { } - public static List getCompileServerApplicationClasspath() { + public static List getBuildProcessApplicationClasspath() { final Set cp = new LinkedHashSet(); cp.add(getResourcePath(Server.class)); for (String path : PathManager.getUtilClassPath()) { cp.add(new File(path)); } // util @@ -114,14 +114,6 @@ public class ClasspathBootstrap { catch (Throwable ignored) { } - final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler(); - if (systemCompiler != null) { - try { - cp.add(getResourcePath(systemCompiler.getClass())); // tools.jar - } - catch (Throwable ignored) { - } - } return new ArrayList(cp); } diff --git a/platform/extensions/src/com/intellij/openapi/extensions/AbstractExtensionPointBean.java b/platform/extensions/src/com/intellij/openapi/extensions/AbstractExtensionPointBean.java index 0f9b3f49b3cc..54b3cd7fda03 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/AbstractExtensionPointBean.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/AbstractExtensionPointBean.java @@ -33,6 +33,10 @@ public abstract class AbstractExtensionPointBean implements PluginAware { myPluginDescriptor = pluginDescriptor; } + public PluginDescriptor getPluginDescriptor() { + return myPluginDescriptor; + } + @NotNull public final Class findClass(final String className) throws ClassNotFoundException { return (Class)Class.forName(className, true, getLoaderForClass()); diff --git a/platform/icons/src/gutter/recursiveMethod.png b/platform/icons/src/gutter/recursiveMethod.png new file mode 100644 index 000000000000..f74592556633 Binary files /dev/null and b/platform/icons/src/gutter/recursiveMethod.png differ diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java index 68f75c8e100e..12cc00f51182 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2012 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -263,13 +263,13 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle final TableColumn levelColumn = treeTable.getColumnModel().getColumn(1); //TODO[max]: better preffered size... - JLabel value = new JLabel(ApplicationBundle.message("option.table.sizing.text")); - final Dimension valueSize = value.getPreferredSize(); - levelColumn.setPreferredWidth(valueSize.width); - levelColumn.setMaxWidth(valueSize.width); - levelColumn.setMinWidth(valueSize.width); - levelColumn.setResizable(false); + //TODO[kb]: Did I fixed it by making the last column floating? + //levelColumn.setPreferredWidth(valueSize.width); + //levelColumn.setMaxWidth(valueSize.width); + //levelColumn.setMinWidth(valueSize.width); + //levelColumn.setResizable(false); + final Dimension valueSize = new JLabel(ApplicationBundle.message("option.table.sizing.text")).getPreferredSize(); treeTable.setPreferredScrollableViewportSize(new Dimension(maxWidth + valueSize.width + 10, 20)); return treeTable; diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index f8265bea7c4b..2f67b1bfefe8 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -519,7 +519,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component if (!isEditing()) { return; } - Component c = myFocusManager.getFocusOwner(); + Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); while (c != null) { if (c instanceof JPopupMenu) { c = ((JPopupMenu)c).getInvoker(); diff --git a/platform/platform-tests/testSrc/com/intellij/psi/tree/IElementTypeTest.java b/platform/platform-tests/testSrc/com/intellij/psi/tree/IElementTypeTest.java index d5915a9f253b..2922cefb6110 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/tree/IElementTypeTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/tree/IElementTypeTest.java @@ -3,13 +3,20 @@ */ package com.intellij.psi.tree; +import com.intellij.lang.Language; import com.intellij.lang.LanguageExtensionPoint; import com.intellij.lang.ParserDefinition; import com.intellij.lang.PsiParser; import com.intellij.lexer.Lexer; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; +import gnu.trove.THashMap; +import gnu.trove.TObjectIntHashMap; + +import java.util.Arrays; +import java.util.Comparator; /** * @author gregsh @@ -20,28 +27,74 @@ public class IElementTypeTest extends LightPlatformCodeInsightFixtureTestCase { @SuppressWarnings("UnusedDeclaration") public void testCount() throws Exception { int count = IElementType.getAllocatedTypesCount(); - System.out.println("Before: " + count +" types"); + System.out.println("Preloaded: " + count +" element types"); LanguageExtensionPoint[] extensions = Extensions.getExtensions(new ExtensionPointName("com.intellij.lang.parserDefinition")); - System.out.println(extensions.length +" definitions"); + System.out.println("ParserDefinitions: " + extensions.length); + THashMap languageMap = new THashMap(); + languageMap.put(Language.ANY, "platform"); + final TObjectIntHashMap map = new TObjectIntHashMap(); for (LanguageExtensionPoint e : extensions) { + String key = e.getPluginDescriptor().getPluginId().getIdString(); + int curCount = IElementType.getAllocatedTypesCount(); ParserDefinition definition = (ParserDefinition)e.getInstance(); + IFileElementType type = definition.getFileNodeType(); + Language language = type.getLanguage(); + languageMap.put(language, key); + if (language.getBaseLanguage() != null && !languageMap.containsKey(language.getBaseLanguage())) { + languageMap.put(language.getBaseLanguage(), key); + } try { - IFileElementType type = definition.getFileNodeType(); Lexer lexer = definition.createLexer(getProject()); PsiParser parser = definition.createParser(getProject()); } catch (UnsupportedOperationException e1) { } + + // language-based calculation: per-class-loading stuff commented + //int diff = IElementType.getAllocatedTypesCount() - curCount; + //map.put(key, map.get(key) + diff); } - System.out.println("After: " + IElementType.getAllocatedTypesCount() +" types"); + // language-based calculation + count = IElementType.getAllocatedTypesCount(); + + for (short i = 0; i < count; i ++ ) { + IElementType type = IElementType.find(i); + Language language = type.getLanguage(); + String key = null; + for (Language cur = language; cur != null && key == null; cur = cur.getBaseLanguage()) { + key = languageMap.get(cur); + } + key = StringUtil.notNullize(key, "unknown"); + map.put(key, map.get(key) + 1); + //if (key.equals("unknown")) System.out.println(type +" " + language); + } + System.out.println("Total: " + IElementType.getAllocatedTypesCount() +" element types"); + + // Show per-plugin statistics + Object[] keys = map.keys(); + Arrays.sort(keys, new Comparator() { + @Override + public int compare(Object o1, Object o2) { + return map.get((String)o2) - map.get((String)o1); + } + }); + int sum = 0; + for (Object key : keys) { + int value = map.get((String)key); + if (value == 0) continue; + sum += value; + System.out.println(" " + key + ": " + value); + } + // leave some index-space for plugin developers assertTrue(IElementType.getAllocatedTypesCount() < 10000); + assertEquals(IElementType.getAllocatedTypesCount(), sum); // output on 11.05.2012 - // Before: 3485 types + // Preloaded: 3485 types // 95 definitions - // After: 7694 types + // Total: 7694 types } } diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionConfigBean.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionConfigBean.java index e1874a75f797..f6eff1434052 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionConfigBean.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/LanguageInjectionConfigBean.java @@ -30,8 +30,5 @@ public class LanguageInjectionConfigBean extends AbstractExtensionPointBean { return myConfigUrl; } - public PluginDescriptor getPluginDescriptor() { - return myPluginDescriptor; - } }