Merge branch 'master' of git.labs.intellij.net:idea/community

This commit is contained in:
Dmitry Cheryasov
2011-01-31 11:35:52 +02:00
29 changed files with 415 additions and 221 deletions
Binary file not shown.
Binary file not shown.
+6 -6
View File
@@ -66,6 +66,12 @@ binding.setVariable("guessHome", {
binding.setVariable("loadProject", {
requireProperty("jdkHome", requireProperty("jdk16.home", guessJdk()))
def mac = isMac()
jdk("IDEA jdk", jdkHome) {
if (!mac) {
classpath "$jdkHome/lib/tools.jar"
}
}
IdeaProjectLoader.loadFromPath(project, "${home}")
binding.ant.patternset(id: "idea.compiler.resources") {
@@ -77,12 +83,6 @@ binding.setVariable("loadProject", {
}
project["compiler.resources.id"] = "idea.compiler.resources"
if (!isMac()) {
project.modules.values().each {
it.classpath << project.resolve("$jdkHome/lib/tools.jar")
}
}
})
requireProperty("home", guessHome())
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiFile;
*/
public interface JoinLinesHandlerDelegate {
ExtensionPointName<JoinLinesHandlerDelegate> EP_NAME = ExtensionPointName.create("com.intellij.joinLinesHandler");
int CANNOT_JOIN = -1;
/**
* Tries to join lines at the specified position of the specified file.
@@ -35,11 +35,8 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPointerManager;
@@ -50,6 +47,8 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.Consumer;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -65,6 +64,13 @@ import java.util.Stack;
public class DocumentationComponent extends JPanel implements Disposable {
private static final DataContext EMPTY_DATA_CONTEXT = new DataContext() {
@Override
public Object getData(@NonNls String dataId) {
return null;
}
};
private static final int MAX_WIDTH = 500;
private static final int MAX_HEIGHT = 300;
private static final int MIN_HEIGHT = 45;
@@ -78,9 +84,10 @@ public class DocumentationComponent extends JPanel implements Disposable {
private boolean myIsEmpty;
private boolean myIsShown;
private final JLabel myElementLabel;
private JBPopup mySettingsPopup;
private Style myFontSizeStyle;
private JSlider myFontSizeSlider;
private JComponent mySettingsPanel;
private MyShowSettingsButton myShowSettingsButton;
private boolean myIgnoreFontSizeSliderChange;
private static class Context {
@@ -197,6 +204,7 @@ public class DocumentationComponent extends JPanel implements Disposable {
final MouseAdapter mouseAdapter = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
myManager.requestFocus();
myShowSettingsButton.hideSettings();
}
};
myEditorPane.addMouseListener(mouseAdapter);
@@ -224,7 +232,29 @@ public class DocumentationComponent extends JPanel implements Disposable {
});
setLayout(new BorderLayout());
add(myScrollPane, BorderLayout.CENTER);
JLayeredPane layeredPane = new JLayeredPane() {
@Override
public void doLayout() {
final Rectangle r = getBounds();
for (Component component : getComponents()) {
if (component instanceof JScrollPane) {
component.setBounds(0, 0, r.width, r.height);
}
else {
Dimension d = component.getPreferredSize();
component.setBounds(r.width - d.width, 2, d.width, d.height);
}
}
}
};
layeredPane.add(myScrollPane);
layeredPane.setLayer(myScrollPane, 0);
mySettingsPanel = createSettingsPanel();
layeredPane.add(mySettingsPanel);
layeredPane.setLayer(mySettingsPanel, JLayeredPane.POPUP_LAYER);
add(layeredPane, BorderLayout.CENTER);
setOpaque(true);
myScrollPane.setViewportBorder(JBScrollPane.createIndentBorder());
final DefaultActionGroup actions = new DefaultActionGroup();
@@ -254,7 +284,7 @@ public class DocumentationComponent extends JPanel implements Disposable {
myControlPanel.add(myToolBar.getComponent(), BorderLayout.WEST);
myControlPanel.add(dummyPanel, BorderLayout.CENTER);
myControlPanel.add(createSettingsButton(), BorderLayout.EAST);
myControlPanel.add(myShowSettingsButton = new MyShowSettingsButton(), BorderLayout.EAST);
myControlPanelVisible = false;
final HyperlinkListener hyperlinkListener = new HyperlinkListener() {
@@ -287,15 +317,16 @@ public class DocumentationComponent extends JPanel implements Disposable {
this(manager, null);
}
private JComponent createSettingsButton() {
String tooltipText = ApplicationBundle.message("quickdoc.tooltip.font.size.by.wheel");
final JPanel fontSizePanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
fontSizePanel.add(new JLabel(ApplicationBundle.message("label.font.size")));
private JComponent createSettingsPanel() {
JPanel result = new JPanel(new FlowLayout(FlowLayout.RIGHT, 3, 0));
result.add(new JLabel(ApplicationBundle.message("label.font.size")));
myFontSizeSlider = new JSlider(JSlider.HORIZONTAL, 0, FontSize.values().length - 1, 3);
myFontSizeSlider.setMinorTickSpacing(1);
myFontSizeSlider.setPaintTicks(true);
myFontSizeSlider.setPaintTrack(true);
myFontSizeSlider.setSnapToTicks(true);
fontSizePanel.add(myFontSizeSlider);
UIUtil.setSliderIsFilled(myFontSizeSlider, true);
result.add(myFontSizeSlider);
myFontSizeSlider.addChangeListener(new ChangeListener() {
@Override
@@ -309,35 +340,14 @@ public class DocumentationComponent extends JPanel implements Disposable {
applyFontSize();
}
});
Presentation presentation = new Presentation();
presentation.setIcon(IconLoader.getIcon("/general/secondaryGroup.png"));
final Ref<JComponent> ref = new Ref<JComponent>();
ActionButton result = new ActionButton(
new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
EditorColorsManager colorsManager = EditorColorsManager.getInstance();
EditorColorsScheme scheme = colorsManager.getGlobalScheme();
setFontSizeSliderSize(scheme.getQuickDocFontSize());
mySettingsPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(fontSizePanel, DocumentationComponent.this)
.setFocusable(false).setBelongsToGlobalPopupStack(false).setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
mySettingsPopup = null;
return true;
}
}).createPopup();
mySettingsPopup.showUnderneathOf(ref.get());
}
},
presentation,
ActionPlaces.JAVADOC_INPLACE_SETTINGS,
ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE
);
ref.set(result);
fontSizePanel.setToolTipText(tooltipText);
String tooltipText = ApplicationBundle.message("quickdoc.tooltip.font.size.by.wheel");
result.setToolTipText(tooltipText);
myFontSizeSlider.setToolTipText(tooltipText);
result.setBorder(IdeBorderFactory.createRoundedBorder());
result.setVisible(false);
result.setOpaque(true);
myFontSizeSlider.setOpaque(true);
return result;
}
@@ -694,10 +704,45 @@ public class DocumentationComponent extends JPanel implements Disposable {
myManager = null;
myHint = null;
myNavigateCallback = null;
if (mySettingsPopup != null) {
Disposer.dispose(mySettingsPopup);
mySettingsPopup = null;
}
private class MyShowSettingsButton extends ActionButton {
MyShowSettingsButton() {
this(new MyShowSettingsAction(), new Presentation(), ActionPlaces.JAVADOC_INPLACE_SETTINGS, ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE);
}
MyShowSettingsButton(AnAction action, Presentation presentation, String place, @NotNull Dimension minimumSize) {
super(action, presentation, place, minimumSize);
myPresentation.setIcon(IconLoader.getIcon("/general/secondaryGroup.png"));
}
public void hideSettings() {
AnActionEvent event = new AnActionEvent(
null, EMPTY_DATA_CONTEXT, ActionPlaces.JAVADOC_INPLACE_SETTINGS, myPresentation, ActionManager.getInstance(), 0
);
myAction.actionPerformed(event);
}
}
private class MyShowSettingsAction extends ToggleAction {
@Override
public boolean isSelected(AnActionEvent e) {
return mySettingsPanel.isVisible();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
if (!state) {
mySettingsPanel.setVisible(false);
return;
}
EditorColorsManager colorsManager = EditorColorsManager.getInstance();
EditorColorsScheme scheme = colorsManager.getGlobalScheme();
setFontSizeSliderSize(scheme.getQuickDocFontSize());
mySettingsPanel.setVisible(true);
}
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2000-2011 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.
*/
/*
* Created by IntelliJ IDEA.
* User: max
* Date: May 20, 2002
* Time: 6:21:42 PM
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiFile;
public interface JoinRawLinesHandlerDelegate extends JoinLinesHandlerDelegate {
int tryJoinRawLines(Document document, PsiFile file, int start, int end);
}
@@ -39,6 +39,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.ui.HintHint;
import com.intellij.ui.LightweightHint;
import com.intellij.util.text.StringSearcher;
import com.intellij.util.ui.UIUtil;
@@ -177,7 +178,7 @@ public class IncrementalSearchHandler {
int y = - hint.getComponent().getPreferredSize().height;
Point p = SwingUtilities.convertPoint(component,x,y,component.getRootPane().getLayeredPane());
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.HIDE_BY_TEXT_CHANGE, 0, false);
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, p, HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.HIDE_BY_TEXT_CHANGE, 0, false, new HintHint(editor, p).setAwtTooltip(false));
PerHintSearchData hintData = new PerHintSearchData(project, label2);
hintData.searchStart = editor.getCaretModel().getOffset();
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
@@ -60,6 +61,10 @@ public class BrowseFilesListener implements ActionListener {
return null;
}
protected void doSetText(@NotNull final String path) {
myTextField.setText(path);
}
public void actionPerformed( ActionEvent e ) {
final VirtualFile fileToSelect = getFileToSelect();
myChooserDescriptor.setTitle(myTitle); // important to set title and description here because a shared descriptor instance can be used
@@ -69,7 +74,7 @@ public class BrowseFilesListener implements ActionListener {
@Override
public void consume(final VirtualFile[] files) {
if (files != null && files.length > 0) {
myTextField.setText(files[0].getPath().replace('/', File.separatorChar));
doSetText(files[0].getPath().replace('/', File.separatorChar));
}
}
});
@@ -18,6 +18,7 @@ package com.intellij.ide.util;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public abstract class PropertiesComponent {
public abstract void unsetValue(String name);
@@ -42,6 +43,11 @@ public abstract class PropertiesComponent {
public abstract String getValue(@NonNls String name);
@NotNull
public String getValue(@NonNls String name, @NotNull String defaultValue) {
return isValueSet(name) ? getValue(name) : defaultValue;
}
public String getOrInit(@NonNls String name, String defaultValue) {
if (!isValueSet(name)) {
setValue(name, defaultValue);
@@ -59,7 +59,7 @@ public class GenericLineWrapPositionStrategy implements LineWrapPositionStrategy
maxPreferredOffsetToUse = maxPreferredOffsetToUse < startOffset ? startOffset : maxPreferredOffsetToUse;
// Try to find out wrap position before preferred offset.
for (int i = maxPreferredOffsetToUse; i > startOffset; i--) {
for (int i = Math.min(maxPreferredOffsetToUse, text.length() - 1); i > startOffset; i--) {
char c = text.charAt(i);
if (c == '\n') {
return i + 1;
@@ -99,7 +99,7 @@ public class GenericLineWrapPositionStrategy implements LineWrapPositionStrategy
// Try to find target offset that is beyond preferred offset.
// Note that we don't consider symbol weights here and just break on the first appropriate position.
if (!allowToBeyondMaxPreferredOffset) {
if (!allowToBeyondMaxPreferredOffset || maxPreferredOffset >= text.length() - 1) {
return maxPreferredOffset;
}
for (int i = maxPreferredOffsetToUse + 1; i < endOffset; i++) {
@@ -238,6 +238,10 @@ public class Messages {
return showDialog(project, message, title, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0, icon);
}
public static int showOkCancelDialog(Component parent, String message, String title, int defaultOptionIndex, int focusedOptionIndex, Icon icon) {
return showDialog(parent, message, title, new String[]{OK_BUTTON, CANCEL_BUTTON}, defaultOptionIndex, focusedOptionIndex, icon);
}
public static int showOkCancelDialog(Component parent, String message, String title, Icon icon) {
return showDialog(parent, message, title, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0, icon);
}
@@ -27,6 +27,9 @@ import java.awt.*;
public class IdeBorderFactory {
public static final int BORDER_ROUNDNESS = 5;
private IdeBorderFactory() {
}
public static Border createBorder() {
return createBorder(SideBorder.ALL);
}
@@ -33,9 +33,10 @@ public abstract class BaseButtonBehavior {
private boolean myPressedByMouse;
private boolean mySelected;
private TimedDeadzone myMouseDeadzone;
private int myActionTrigger;
public BaseButtonBehavior(JComponent component) {
this(component, TimedDeadzone.DEFAULT);
}
@@ -45,6 +46,12 @@ public abstract class BaseButtonBehavior {
myMouseDeadzone = new TimedDeadzone(mouseDeadzoneTime, Alarm.ThreadToUse.SWING_THREAD);
myComponent.addMouseListener(new MyMouseListener());
myComponent.addMouseMotionListener(new MyMouseMotionListener());
setActionTrigger(MouseEvent.MOUSE_RELEASED);
}
public void setActionTrigger(int trigger) {
assert trigger == MouseEvent.MOUSE_PRESSED || trigger == MouseEvent.MOUSE_RELEASED;
myActionTrigger = trigger;
}
public final boolean isHovered() {
@@ -111,7 +118,11 @@ public abstract class BaseButtonBehavior {
setPressedByMouse(true);
repaintComponent();
if (myActionTrigger == MouseEvent.MOUSE_PRESSED) {
if (execute(e)) return;
} else {
repaintComponent();
}
}
@@ -121,21 +132,30 @@ public abstract class BaseButtonBehavior {
setPressedByMouse(false);
Point point = e.getPoint();
if (point.x < 0 || point.x > myComponent.getWidth()) return;
if (point.y < 0 || point.y > myComponent.getHeight()) return;
repaintComponent();
execute(e);
if (myActionTrigger == MouseEvent.MOUSE_RELEASED) {
if (execute(e)) return;
} else {
repaintComponent();
}
}
finally {
myWasPressedOnFocusTransfer = false;
}
}
private boolean execute(MouseEvent e) {
Point point = e.getPoint();
if (point.x < 0 || point.x > myComponent.getWidth()) return true;
if (point.y < 0 || point.y > myComponent.getHeight()) return true;
repaintComponent();
BaseButtonBehavior.this.execute(e);
return false;
}
private boolean passIfNeeded(final MouseEvent e, boolean considerDeadzone) {
final boolean actionClick = UIUtil.isActionClick(e, MouseEvent.MOUSE_RELEASED) || UIUtil.isActionClick(e, MouseEvent.MOUSE_PRESSED);
final boolean actionClick = UIUtil.isActionClick(e, myActionTrigger);
if (!actionClick || (considerDeadzone && myMouseDeadzone.isWithin())) {
pass(e);
@@ -15,8 +15,10 @@
*/
package com.intellij.ide.startup.impl;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.caches.CacheUpdater;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.notification.*;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -27,12 +29,15 @@ import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.DumbServiceImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.io.storage.HeavyProcessLatch;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import javax.swing.event.HyperlinkEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
@@ -144,6 +149,22 @@ public class StartupManagerImpl extends StartupManagerEx {
if (!app.isUnitTestMode()) {
VirtualFileManager.getInstance().refresh(!app.isHeadlessEnvironment());
}
if (SystemInfo.isMac && SystemInfo.is64Bit && "10.6".compareTo(SystemInfo.OS_VERSION) <= 0) {
if (Registry.is("ide.firstStartup")) {
Notification n =
new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "64-bit System Information", "You IntelliJ IDEA now running in 64-bit mode.<br>" +
"You may reduce memory, used by IntelliJ IDEA, by running it in 32-bit mode. " +
"<a href=\"http://devnet.jetbrains.net/docs/DOC-1232\">Click for details</a>", NotificationType.INFORMATION, new NotificationListener() {
@Override
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
BrowserUtil.launchBrowser(event.getURL().toString());
}
});
Notifications.Bus.notify(n, NotificationDisplayType.STICKY_BALLOON, null);
Registry.get("ide.firstStartup").setValue(false);
}
}
}
private void startCacheUpdate() {
@@ -472,8 +472,7 @@ public class SoftWrapApplianceManager implements FoldingListener, DocumentListen
return i;
}
}
assert end > 0;
return end - 1;
return end;
}
private static int calculateWidthInColumns(char c, int widthInPixels, int spaceWithInPixels) {
@@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl.content;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.ui.BaseButtonBehavior;
import com.intellij.util.ui.TimedDeadzone;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@@ -44,7 +45,8 @@ class ContentTabLabel extends BaseLabel {
}
}
};
myBehavior.setActionTrigger(MouseEvent.MOUSE_PRESSED);
myBehavior.setMouseDeadzone(TimedDeadzone.NULL);
}
public void update() {
@@ -30,6 +30,7 @@ actionSystem.quickAccessModifiers=
actionSystem.quickAccessShowSpotsTime=1500
actionSystem.win.supressAlt=true
ide.firstStartup=true
ide.debugMode=false
ide.debugMode.description=Record additonal information to make bug reports more informative
ide.forcedShowTooltip=alt
@@ -96,7 +96,7 @@
<fileBasedIndex implementation="com.intellij.xml.index.XmlNamespaceIndex"/>
<fileBasedIndex implementation="com.intellij.html.index.Html5CustomAttributesIndex"/>
<include.provider implementation="com.intellij.xml.util.XIncludeProvider"/>
<indexedRootsProvider implementation="com.intellij.xml.index.ExternalResourcesRootsProvider"/>
<indexedRootsProvider implementation="com.intellij.javaee.ExternalResourcesRootsProvider"/>
<applicationService serviceInterface="com.intellij.application.options.editor.WebEditorOptions"
serviceImplementation="com.intellij.application.options.editor.WebEditorOptions"/>
@@ -85,6 +85,10 @@ public class Foundation {
return myFoundationLibrary.objc_getClass(clazz);
}
public static String fullUserName() {
return toStringViaUTF8(myFoundationLibrary.NSFullUserName());
}
/**
* Return a CFString as an ID, toll-free bridged to NSString.
* <p/>
@@ -25,6 +25,8 @@ import com.sun.jna.Pointer;
public interface FoundationLibrary extends Library {
void NSLog(Pointer pString, Object thing);
ID NSFullUserName();
ID objc_allocateClassPair(ID supercls, String name, int extraBytes);
void objc_registerClassPair(ID cls);
@@ -1762,5 +1762,21 @@ public class UIUtil {
return null;
}
public static void scrollListToVisibleIfNeeded(@NotNull final JList list) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final int selectedIndex = list.getSelectedIndex();
if (selectedIndex >= 0) {
final Rectangle visibleRect = list.getVisibleRect();
final Rectangle cellBounds = list.getCellBounds(selectedIndex, selectedIndex);
if (!visibleRect.contains(cellBounds)) {
list.scrollRectToVisible(cellBounds);
}
}
}
});
}
}
@@ -21,6 +21,7 @@ import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ConditionalExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement;
import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeSpec;
import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
@@ -41,7 +42,7 @@ public class UnaryExpressionNotPlusMinus implements GroovyElementTypes {
if (builder.getTokenType() == mLPAREN) {
final ReferenceElement.ReferenceElementResult result = parseTypeCast(builder);
if (result != fail) {
if (UnaryExpression.parse(builder, parser) || result == ReferenceElement.ReferenceElementResult.mustBeType) {
if (ConditionalExpression.parse(builder, parser) || result == ReferenceElement.ReferenceElementResult.mustBeType) {
marker.done(CAST_EXPRESSION);
return true;
} else {
@@ -187,6 +187,8 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
public void testtypecast$una4() throws Throwable { doTest(); }
public void testtypecast$una5() throws Throwable { doTest(); }
public void testtypecast$una6() throws Throwable { doTest(); }
public void testtypecast$elvis() throws Throwable { doTest(); }
public void testtypecast$conditional() throws Throwable { doTest(); }
public void testAtHang() throws Throwable { doTest(); }
public void testDollar() throws Throwable { doTest(); }
@@ -0,0 +1,35 @@
def list = (List<String>) foo?bar: bar
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('list')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Typecast expression
PsiElement(()('(')
Type element
Reference element
PsiElement(identifier)('List')
Type arguments
PsiElement(<)('<')
Type element
Reference element
PsiElement(identifier)('String')
PsiElement(>)('>')
PsiElement())(')')
PsiWhiteSpace(' ')
Conditional expression
Reference expression
PsiElement(identifier)('foo')
PsiElement(?)('?')
Reference expression
PsiElement(identifier)('bar')
PsiElement(:)(':')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('bar')
@@ -0,0 +1,32 @@
def list = (List<String>) foo?: bar
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('list')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Typecast expression
PsiElement(()('(')
Type element
Reference element
PsiElement(identifier)('List')
Type arguments
PsiElement(<)('<')
Type element
Reference element
PsiElement(identifier)('String')
PsiElement(>)('>')
PsiElement())(')')
PsiWhiteSpace(' ')
Elvis expression
Reference expression
PsiElement(identifier)('foo')
PsiElement(?:)('?:')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('bar')
@@ -17,6 +17,7 @@ package com.intellij.javaee;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.application.options.ReplacePathToMacroMap;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
@@ -26,6 +27,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlFile;
@@ -40,6 +42,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.net.URL;
import java.util.*;
/**
@@ -61,18 +64,18 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
private final Set<String> myIgnoredResources = new HashSet<String>();
private final AtomicNotNullLazyValue<Map<String, Map<String, String>>> myStdResources = new AtomicNotNullLazyValue<Map<String, Map<String, String>>>() {
private final AtomicNotNullLazyValue<Map<String, Map<String, Resource>>> myStdResources = new AtomicNotNullLazyValue<Map<String, Map<String, Resource>>>() {
@NotNull
@Override
protected Map<String, Map<String, String>> compute() {
protected Map<String, Map<String, Resource>> compute() {
return computeStdResources();
}
};
private String myDefaultHtmlDoctype = XmlUtil.XHTML_URI;
protected Map<String, Map<String, String>> computeStdResources() {
protected Map<String, Map<String, Resource>> computeStdResources() {
ResourceRegistrarImpl registrar = new ResourceRegistrarImpl();
for (StandardResourceProvider provider : Extensions.getExtensions(StandardResourceProvider.EP_NAME)) {
provider.registerResources(registrar);
@@ -128,7 +131,7 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
}
public String getResourceLocation(@NonNls String url, String version) {
String result = getUserResourse(url, version);
String result = getUserResource(url, version);
if (result == null) {
result = getStdResource(url, version);
}
@@ -141,19 +144,25 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
@Override
@Nullable
public String getUserResourse(Project project, String url, String version) {
String resourse = getProjectResources(project).getUserResourse(url, version);
return resourse == null ? getUserResourse(url, version) : resourse;
String resourse = getProjectResources(project).getUserResource(url, version);
return resourse == null ? getUserResource(url, version) : resourse;
}
@Override
@Nullable
public String getStdResource(String url, String version) {
Map<String, String> map = getMap(myStdResources.getValue(), version, false);
return map != null ? map.get(url) : null;
Map<String, Resource> map = getMap(myStdResources.getValue(), version, false);
if (map != null) {
Resource resource = map.get(url);
return resource == null ? null : resource.getResourceUrl();
}
else {
return null;
}
}
@Nullable
private String getUserResourse(String url, String version) {
private String getUserResource(String url, String version) {
Map<String, String> map = getMap(myResources, version, false);
return map != null ? map.get(url) : null;
}
@@ -184,39 +193,21 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
public String[] getResourceUrls(@Nullable final FileType fileType, @NonNls final String version, final boolean includeStandard) {
final List<String> result = new LinkedList<String>();
addResourcesFromMap(fileType, result, version, myResources);
addResourcesFromMap(result, version, myResources);
if (includeStandard) {
addResourcesFromMap(fileType, result, version, myStdResources.getValue());
addResourcesFromMap(result, version, myStdResources.getValue());
}
return ArrayUtil.toStringArray(result);
}
private static void addResourcesFromMap(@Nullable final FileType fileType,
final List<String> result,
private static <T> void addResourcesFromMap(final List<String> result,
String version,
Map<String, Map<String, String>> resourcesMap) {
Map<String, String> resources = getMap(resourcesMap, version, false);
Map<String, Map<String, T>> resourcesMap) {
Map<String, T> resources = getMap(resourcesMap, version, false);
if (resources == null) return;
final Set<String> keySet = resources.keySet();
for (String key : keySet) {
String resource = resources.get(key);
if (fileType != null) {
String defaultExtension = fileType.getDefaultExtension();
if (resource.endsWith(defaultExtension) &&
resource.length() > defaultExtension.length() &&
resource.charAt(resource.length() - defaultExtension.length() - 1) == '.') {
result.add(key);
}
}
else {
result.add(key);
}
}
result.addAll(resources.keySet());
}
public void addResource(String url, String location) {
@@ -399,15 +390,11 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
}
}
public List<String> getStandardResources() {
ArrayList<String> strings = new ArrayList<String>();
Collection<Map<String, String>> maps = myStdResources.getValue().values();
for (Map<String, String> map : maps) {
strings.addAll(map.values());
}
return strings;
Collection<Map<String, Resource>> getStandardResources() {
return myStdResources.getValue().values();
}
private final static NotNullLazyKey<ProjectResources, Project> INSTANCE_CACHE = ServiceManager.createLazyKey(ProjectResources.class);
private static ExternalResourceManagerImpl getProjectResources(Project project) {
@@ -431,5 +418,53 @@ public class ExternalResourceManagerImpl extends ExternalResourceManagerEx imple
fireExternalResourceChanged();
}
static class Resource {
String file;
Class clazz;
@Nullable
String getResourceUrl() {
if (clazz == null) return file;
final URL resource = clazz.getResource(file);
clazz = null;
if (resource == null) {
String message = "Cannot find standard resource. filename:" + file + " class=" + clazz;
if (ApplicationManager.getApplication().isUnitTestMode()) {
LOG.error(message);
}
else {
LOG.warn(message);
}
return null;
}
String path = FileUtil.unquote(resource.toString());
// this is done by FileUtil for windows
path = path.replace('\\','/');
file = path;
return path;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Resource resource = (Resource)o;
if (clazz != resource.clazz) return false;
if (file != null ? !file.equals(resource.file) : resource.file != null) return false;
return true;
}
@Override
public int hashCode() {
return file.hashCode();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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,20 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xml.index;
package com.intellij.javaee;
import com.intellij.codeInsight.daemon.impl.quickfix.FetchExtResourceAction;
import com.intellij.javaee.ExternalResourceManagerEx;
import com.intellij.javaee.ExternalResourceManagerImpl;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.indexing.IndexableSetContributor;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@@ -34,20 +34,34 @@ import java.util.Set;
*/
public class ExternalResourcesRootsProvider extends IndexableSetContributor {
private final NotNullLazyValue<Set<String>> myStandardResources = new NotNullLazyValue<Set<String>>() {
@NotNull
@Override
protected Set<String> compute() {
ExternalResourceManagerImpl manager = (ExternalResourceManagerImpl)ExternalResourceManagerEx.getInstance();
Collection<Map<String,ExternalResourceManagerImpl.Resource>> resources = manager.getStandardResources();
Set<ExternalResourceManagerImpl.Resource> dirs = new HashSet<ExternalResourceManagerImpl.Resource>();
for (Map<String, ExternalResourceManagerImpl.Resource> map : resources) {
for (ExternalResourceManagerImpl.Resource resource : map.values()) {
ExternalResourceManagerImpl.Resource dir = new ExternalResourceManagerImpl.Resource();
int i = resource.file.lastIndexOf("/");
dir.file = i > 0 ? resource.file.substring(0, i) : resource.file;
dirs.add(dir);
}
}
HashSet<String> set = new HashSet<String>();
for (ExternalResourceManagerImpl.Resource dir : dirs) {
String url = dir.getResourceUrl();
ContainerUtil.addIfNotNull(set, url);
}
return set;
}
};
public Set<VirtualFile> getAdditionalRootsToIndex() {
ExternalResourceManagerImpl manager = (ExternalResourceManagerImpl)ExternalResourceManagerEx.getInstance();
List<String> urls = manager.getStandardResources();
Set<String> dirs = new HashSet<String>(ContainerUtil.map(urls, new Function<String, String>() {
@Override
public String fun(String s) {
int endIndex = s.lastIndexOf('/');
return endIndex > 0 ? s.substring(0, endIndex) : s;
}
}));
HashSet<VirtualFile> roots = new HashSet<VirtualFile>();
for (String url : dirs) {
for (String url : myStandardResources.getValue()) {
VirtualFile file = VfsUtil.findRelativeFile(url, null);
if (file != null) {
roots.add(file);
@@ -39,7 +39,7 @@ public class ProjectResources extends ExternalResourceManagerImpl implements Per
}
@Override
protected Map<String, Map<String, String>> computeStdResources() {
protected Map<String, Map<String, Resource>> computeStdResources() {
return Collections.emptyMap();
}
@@ -16,15 +16,9 @@
package com.intellij.javaee;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -34,9 +28,8 @@ import java.util.Map;
*/
public class ResourceRegistrarImpl implements ResourceRegistrar {
private final Map<String, Map<String, String>> myResources = new HashMap<String, Map<String, String>>();
private final Map<String, Map<String, ExternalResourceManagerImpl.Resource>> myResources = new HashMap<String, Map<String, ExternalResourceManagerImpl.Resource>>();
private final List<String> myIgnored = new ArrayList<String>();
private final Map<ClassLoader, Map<String, VirtualFile>> myCache = CollectionFactory.hashMap();
public void addStdResource(@NonNls String resource, @NonNls String fileName) {
addStdResource(resource, null, fileName, getClass());
@@ -47,22 +40,12 @@ public class ResourceRegistrarImpl implements ResourceRegistrar {
}
public void addStdResource(@NonNls String resource, @NonNls String version, @NonNls String fileName, Class klass) {
final String file = getFile(fileName, klass);
if (file != null) {
//saveCache(fileName, klass, file);
final Map<String, String> map = ExternalResourceManagerImpl.getMap(myResources, version, true);
assert map != null;
map.put(resource, file);
}
else {
String message = "Cannot find standard resource. filename:" + fileName + " klass=" + klass;
if (ApplicationManager.getApplication().isUnitTestMode()) {
ExternalResourceManagerImpl.LOG.error(message);
}
else {
ExternalResourceManagerImpl.LOG.warn(message);
}
}
final Map<String, ExternalResourceManagerImpl.Resource> map = ExternalResourceManagerImpl.getMap(myResources, version, true);
assert map != null;
ExternalResourceManagerImpl.Resource res = new ExternalResourceManagerImpl.Resource();
res.file = fileName;
res.clazz = klass == null ? ExternalResourceManagerImpl.class : klass;
map.put(resource, res);
}
public void addIgnoredResource(@NonNls String url) {
@@ -85,77 +68,7 @@ public class ResourceRegistrarImpl implements ResourceRegistrar {
addStdResource(resource, version, ExternalResourceManagerImpl.STANDARD_SCHEMAS + fileName, clazz);
}
@Nullable
private String getFile(String name, Class klass) {
/*
VirtualFile file = findUsingCache(name, klass);
if (file != null) {
return file;
}
*/
final URL resource = klass.getResource(name);
if (resource == null) return null;
String path = FileUtil.unquote(resource.toString());
// this is done by FileUtil for windows
path = path.replace('\\','/');
return path;//VfsUtil.findRelativeFile(path, null);
}
@Nullable
private VirtualFile findUsingCache(String name, Class klass) {
if (!name.startsWith("/")) return null;
final Map<String, VirtualFile> cache = myCache.get(klass.getClassLoader());
if (cache == null) return null;
int end = name.length();
while (true) {
final int i = name.lastIndexOf('/', end);
if (i < 0) break;
final VirtualFile existing = cache.get(name.substring(0, i));
if (existing != null) {
final VirtualFile guess = existing.findFileByRelativePath(name.substring(i + 1));
if (guess != null) {
return guess;
}
}
end = i - 1;
}
return null;
}
private void saveCache(String name, Class klass, VirtualFile file) {
if (!name.startsWith("/")) return;
final ClassLoader loader = klass.getClassLoader();
Map<String, VirtualFile> cache = myCache.get(loader);
if (cache == null) {
myCache.put(loader, cache = CollectionFactory.hashMap());
}
String parent = name;
VirtualFile current = file;
while (true) {
if (current.equals(cache.get(parent))) break;
cache.put(parent, current);
final int i = parent.lastIndexOf('/');
if (i <= 0) break;
if (!parent.substring(i + 1).equals(current.getName())) {
break;
}
parent = parent.substring(0, i);
current = current.getParent();
}
}
public Map<String, Map<String, String>> getResources() {
public Map<String, Map<String, ExternalResourceManagerImpl.Resource>> getResources() {
return myResources;
}