diff --git a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java index 2d7dd2f7ca16..64dafbc05190 100644 --- a/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java +++ b/java/execution/impl/src/com/intellij/execution/ui/ConfigurationModuleSelector.java @@ -91,7 +91,7 @@ public class ConfigurationModuleSelector { myModules.setSelectedItem(configuration.getConfigurationModule().getModule()); } - public static boolean isModuleAccepted(final Module module) { + public boolean isModuleAccepted(final Module module) { return ModuleTypeManager.getInstance().isClasspathProvider(ModuleType.get(module)); } diff --git a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java index 41ce665cc145..91d04d04dc3a 100644 --- a/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java +++ b/java/idea-ui/src/com/intellij/ide/impl/NewProjectUtil.java @@ -19,6 +19,7 @@ */ package com.intellij.ide.impl; +import com.intellij.ide.GeneralSettings; import com.intellij.ide.util.newProjectWizard.AddModuleWizard; import com.intellij.ide.util.projectWizard.ProjectBuilder; import com.intellij.openapi.application.ApplicationManager; @@ -209,7 +210,7 @@ public class NewProjectUtil { Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); if (openProjects.length > 0) { int exitCode = ProjectUtil.confirmOpenNewProject(true); - if (exitCode == 0) { // this window option + if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) { ProjectUtil.closeAndDispose(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1]); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java index 11cdf6305f98..38eb67cdd892 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveCache.java @@ -27,13 +27,17 @@ import com.intellij.openapi.util.NotNullLazyKey; import com.intellij.psi.*; import com.intellij.psi.impl.AnyPsiChangeListener; import com.intellij.psi.impl.DebugUtil; +import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.source.PsiClassReferenceType; +import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.containers.ConcurrentWeakHashMap; +import com.intellij.util.containers.WeakHashMap; +import com.intellij.util.containers.WeakList; import com.intellij.util.messages.MessageBus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,6 +57,9 @@ public class JavaResolveCache { private final ConcurrentMap myCalculatedTypes = new ConcurrentWeakHashMap(); private final ConcurrentMap myCachedReferencesInPsiTypes = new ConcurrentWeakHashMap(); + // e.g. given FileOutputStream os, os2; + // PsiJavaCodeReferenceElement("FileOutputStream") -> [ PsiReferenceExpression("os"), PsiReferenceExpression("os2") ] + private final Map> myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere = new WeakHashMap>(); private final Map myVarToConstValueMapPhysical; private final Map myVarToConstValueMapNonPhysical; @@ -78,6 +85,7 @@ public class JavaResolveCache { private void clearCaches(boolean isPhysical) { myCalculatedTypes.clear(); myCachedReferencesInPsiTypes.clear(); + myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.clear(); if (isPhysical) { myVarToConstValueMapPhysical.clear(); } @@ -96,8 +104,15 @@ public class JavaResolveCache { if (type == null) { type = TypeConversionUtil.NULL_TYPE; } - type = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type); + PsiType stored = ConcurrencyUtil.cacheOrGet(myCalculatedTypes, expr, type); + + if (stored == type && DebugUtil.DO_EXPENSIVE_CHECKS) { + registerDiagnosticsHooks(expr, type); + } + + type = stored; } + if (!type.isValid()) { if (expr.isValid()) { PsiJavaCodeReferenceElement refInside = type instanceof PsiClassReferenceType ? ((PsiClassReferenceType)type).getReference() : null; @@ -109,44 +124,86 @@ public class JavaResolveCache { } } - if (DebugUtil.DO_EXPENSIVE_CHECKS) { - if (type instanceof PsiClassReferenceType) { - PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference(); - ConcurrencyUtil.cacheOrGet(myCachedReferencesInPsiTypes, reference, type); - DebugUtil.trackInvalidation(reference, "Reference inside PsiClassReferenceType was invalidated", new Processor() { - @Override - public boolean process(PsiElement element) { - PsiType cached = myCalculatedTypes.get(element); - if (cached != null) { - LOG.error(element + " (inside ref) is invalid and yet it is still cached: " + cached); - } - PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); - if (cachedRef != null) { - LOG.error(element + " (inside ref) is invalid and yet it is still cached in ref cache: " + cachedRef); - } - return true; - } - }); + return type == TypeConversionUtil.NULL_TYPE ? null : type; + } + private void registerDiagnosticsHooks(T expr, PsiType type) { + if (type instanceof PsiClassReferenceType) { + PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType)type).getReference(); + ConcurrencyUtil.cacheOrGet(myCachedReferencesInPsiTypes, reference, type); + synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) { + WeakList refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(reference); + if (refsTo==null) { + refsTo = new WeakList(); + myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.put(reference, refsTo); + } + refsTo.add(expr); } - DebugUtil.trackInvalidation(expr, "Expression invalidated", new Processor() { + final PsiFile dummyHolder = reference.getContainingFile(); + if (dummyHolder != null && !dummyHolder.isPhysical()) { + PsiElement physicalContext = dummyHolder.getContext(); + PsiFile physicalFile; + if (physicalContext != null && + (physicalFile = physicalContext.getContainingFile()) != null && + physicalFile.getVirtualFile() != null && + !((PsiManagerEx)PsiManager.getInstance(dummyHolder.getProject())).isAssertOnFileLoading(physicalFile.getVirtualFile())) { + DebugUtil.trackInvalidation(physicalContext, "dummy holder was invalidated", new Processor() { + @Override + public boolean process(PsiElement element) { + DebugUtil.onInvalidated((TreeElement)dummyHolder.getNode()); + return true; + } + }); + } + } + + DebugUtil.trackInvalidation(reference, "Reference inside PsiClassReferenceType was invalidated", new Processor() { @Override public boolean process(PsiElement element) { PsiType cached = myCalculatedTypes.get(element); if (cached != null) { - LOG.error(element + " is invalid and yet it is still cached: " + cached); + LOG.error(element + " (inside ref) is invalid and yet it is still cached: " + cached); } - PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); if (cachedRef != null) { - LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef); + LOG.error(element + " (inside ref) is invalid and yet it is still cached in ref cache: " + cachedRef); } + + + synchronized (myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere) { + WeakList refsTo = myCachedReferenceIn_PsiClassReferenceType_To_ListOfReferencesOfThisType_CachedHere.get(element); + if (refsTo != null) { + for (PsiElement ref : refsTo) { + PsiType cachedT = myCalculatedTypes.get(ref); + if (cachedT != null && !cachedT.isValid()) { + LOG.error("During invalidation of " + element + " ("+element.getClass()+")"+ + " cached type " + cachedT + " of the ref "+ref+" ("+ref.getClass()+")"+ + " became invalid and yet it is still cached" + ); + } + } + } + } + return true; } }); } + DebugUtil.trackInvalidation(expr, "Expression invalidated", new Processor() { + @Override + public boolean process(PsiElement element) { + PsiType cached = myCalculatedTypes.get(element); + if (cached != null) { + LOG.error(element + " is invalid and yet it is still cached: " + cached); + } - return type == TypeConversionUtil.NULL_TYPE ? null : type; + PsiType cachedRef = myCachedReferencesInPsiTypes.get(element); + if (cachedRef != null) { + LOG.error(element + " is invalid and yet it is still cached (inside PsiType): " + cachedRef); + } + return true; + } + }); } @Nullable diff --git a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java index 90aa13fdb388..c8cb5460e197 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DebugUtil.java @@ -490,7 +490,7 @@ public class DebugUtil { } public static void onInvalidated(@NotNull TreeElement treeElement) { - treeElement.acceptTree(new RecursiveTreeElementWalkingVisitor() { + treeElement.acceptTree(new RecursiveTreeElementWalkingVisitor(false) { @Override protected void visitNode(TreeElement element) { List>> callbacks = element.getUserData(TRACK_INVALIDATION_KEY); @@ -501,6 +501,7 @@ public class DebugUtil { if (psi != null) callback.process(psi); } } + super.visitNode(element); } }); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java index dfe94b45c3e1..4dec3b2a23b6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPassFactory.java @@ -54,7 +54,7 @@ public class ExternalToolPassFactory extends AbstractProjectComponent implements @Override @Nullable public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file, @NotNull final Editor editor) { - TextRange textRange = FileStatusMap.getDirtyTextRange(editor, Pass.EXTERNAL_TOOLS); + TextRange textRange = file.getTextRange(); if (textRange == null || !externalAnnotatorsDefined(file)) { return null; } diff --git a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java index 142faa3a4637..52415124e3e7 100644 --- a/platform/platform-api/src/com/intellij/ide/GeneralSettings.java +++ b/platform/platform-api/src/com/intellij/ide/GeneralSettings.java @@ -52,7 +52,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli private String myLastProjectLocation; private boolean mySearchInBackground; private boolean myConfirmExit = true; - private int myConfirmOpenNewProject = -1; + private int myConfirmOpenNewProject = OPEN_PROJECT_ASK; @NonNls private static final String ELEMENT_OPTION = "option"; @NonNls private static final String ATTRIBUTE_NAME = "name"; @NonNls private static final String ATTRIBUTE_VALUE = "value"; @@ -74,7 +74,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli @NonNls private static final String OPTION_USE_CYCLIC_BUFFER = "useCyclicBuffer"; @NonNls private static final String OPTION_SEARCH_IN_BACKGROUND = "searchInBackground"; @NonNls private static final String OPTION_CONFIRM_EXIT = "confirmExit"; - @NonNls private static final String OPTION_CONFIRM_OPEN_NEW_PROJECT = "confirmOpenNewProject"; + @NonNls private static final String OPTION_CONFIRM_OPEN_NEW_PROJECT = "confirmOpenNewProject2"; @NonNls private static final String OPTION_CYCLIC_BUFFER_SIZE = "cyclicBufferSize"; @NonNls private static final String OPTION_LAST_PROJECT_LOCATION = "lastProjectLocation"; @Deprecated @@ -331,7 +331,7 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli myConfirmOpenNewProject = Integer.valueOf(value).intValue(); } catch (Exception ex) { - myConfirmOpenNewProject = -1; + myConfirmOpenNewProject = OPEN_PROJECT_ASK; } } @@ -477,9 +477,9 @@ public class GeneralSettings implements NamedJDOMExternalizable, ExportableAppli /** * @return *
    - *
  • 0 if new project should be opened in new window - *
  • 1 if new project should be opened in same window - *
  • -1 if a confirmation dialog should be shown + *
  • {@link GeneralSettings#OPEN_PROJECT_NEW_WINDOW} if new project should be opened in new window + *
  • {@link GeneralSettings#OPEN_PROJECT_SAME_WINDOW} if new project should be opened in same window + *
  • {@link GeneralSettings#OPEN_PROJECT_ASK} if a confirmation dialog should be shown *
*/ public int getConfirmOpenNewProject() { diff --git a/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java index 2797c874b3ff..1e75289c3297 100644 --- a/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java +++ b/platform/platform-impl/src/com/intellij/ide/ClipboardSynchronizer.java @@ -184,6 +184,7 @@ public class ClipboardSynchronizer implements ApplicationComponent { private static class MacClipboardHandler extends ClipboardHandler { private static final String CLIPBOARD_CONTENTS = "CLIPBOARD_CONTENTS"; + private static final String MAC_CLIPBOARD_SYNC_ACTIVE = "Mac.Clipboard.Sync.Active"; private Pair myFullTransferable; private static Callback myClipboardQueryCallback = new Callback() { @@ -195,7 +196,7 @@ public class ClipboardSynchronizer implements ApplicationComponent { pane.putClientProperty(CLIPBOARD_CONTENTS, transferable); } - pane.putClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING, null); + pane.putClientProperty(MAC_CLIPBOARD_SYNC_ACTIVE, null); } } }; @@ -298,8 +299,8 @@ public class ClipboardSynchronizer implements ApplicationComponent { .invoke(synchronizer, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("run:"), null, false); - pane.putClientProperty(MacUtil.MAC_NATIVE_WINDOW_SHOWING, Boolean.TRUE); - MacUtil.startModal(pane); + pane.putClientProperty(MAC_CLIPBOARD_SYNC_ACTIVE, Boolean.TRUE); + MacUtil.startModal(pane, MAC_CLIPBOARD_SYNC_ACTIVE); Foundation.cfRelease(synchronizer); diff --git a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java index 3fc1d36b617c..c748cdeb847b 100644 --- a/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/GeneralSettingsConfigurable.java @@ -67,7 +67,7 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable= 0) || (!myComponent.myConfirmFrameToOpenCheckBox.isSelected() == openProjectOption < 0); + boolean savedOptionIsAsk = openProjectOption == GeneralSettings.OPEN_PROJECT_ASK; + isModified |= myComponent.myConfirmFrameToOpenCheckBox.isSelected() != savedOptionIsAsk; int inactiveTimeout = -1; try { inactiveTimeout = Integer.parseInt(myComponent.myTfInactiveTimeout.getText()); } - catch (NumberFormatException e) { + catch (NumberFormatException ignored) { } isModified |= inactiveTimeout > 0 && settings.getInactiveTimeout() != inactiveTimeout; @@ -141,7 +142,7 @@ public class GeneralSettingsConfigurable extends CompositeConfigurable 0) { int exitCode = confirmOpenNewProject(false); - if (exitCode == 0) { // this window option + if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) { if (!closeAndDispose(projectToClose != null ? projectToClose : openProjects[openProjects.length - 1])) return null; } - else if (exitCode != 1) { // not in a new window + else if (exitCode != GeneralSettings.OPEN_PROJECT_NEW_WINDOW) { return null; } } @@ -192,30 +192,33 @@ public class ProjectUtil { } /** - * @return 0 - this window - * 1 - new window - * 2 - cancel + * @return {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_SAME_WINDOW} + * {@link com.intellij.ide.GeneralSettings#OPEN_PROJECT_NEW_WINDOW} + * {@link com.intellij.openapi.ui.Messages#CANCEL} - if user canceled the dialog * @param isNewProject */ public static int confirmOpenNewProject(boolean isNewProject) { final GeneralSettings settings = GeneralSettings.getInstance(); - if (settings.getConfirmOpenNewProject() == GeneralSettings.OPEN_PROJECT_ASK) { + int confirmOpenNewProject = settings.getConfirmOpenNewProject(); + if (confirmOpenNewProject == GeneralSettings.OPEN_PROJECT_ASK) { if (isNewProject) { - return Messages.showYesNoDialog(IdeBundle.message("prompt.open.project.in.new.frame"), - IdeBundle.message("title.new.project"), - IdeBundle.message("button.existingframe"), - IdeBundle.message("button.newframe"), - Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption()); + int exitCode = Messages.showYesNoDialog(IdeBundle.message("prompt.open.project.in.new.frame"), + IdeBundle.message("title.new.project"), + IdeBundle.message("button.existingframe"), + IdeBundle.message("button.newframe"), + Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption()); + return exitCode == 0 ? GeneralSettings.OPEN_PROJECT_SAME_WINDOW : GeneralSettings.OPEN_PROJECT_NEW_WINDOW; } else { - return Messages.showYesNoCancelDialog(IdeBundle.message("prompt.open.project.in.new.frame"), - IdeBundle.message("title.open.project"), - IdeBundle.message("button.existingframe"), IdeBundle.message("button.newframe"), - CommonBundle.getCancelButtonText(), Messages.getQuestionIcon(), - new ProjectNewWindowDoNotAskOption()); + int exitCode = Messages.showYesNoCancelDialog(IdeBundle.message("prompt.open.project.in.new.frame"), + IdeBundle.message("title.open.project"), + IdeBundle.message("button.existingframe"), IdeBundle.message("button.newframe"), + CommonBundle.getCancelButtonText(), Messages.getQuestionIcon(), + new ProjectNewWindowDoNotAskOption()); + return exitCode == 0 ? GeneralSettings.OPEN_PROJECT_SAME_WINDOW : exitCode == 1 ? GeneralSettings.OPEN_PROJECT_NEW_WINDOW : Messages.CANCEL; } } - return settings.getConfirmOpenNewProject(); + return confirmOpenNewProject; } private static boolean isSameProject(String path, Project p) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java index a6d987f4f0ff..2585c25ab461 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorHistoryManager.java @@ -154,7 +154,7 @@ public final class EditorHistoryManager extends AbstractProjectComponent impleme @Nullable FileEditorProvider fallbackProvider, final boolean changeEntryOrderOnly) { - if (file == null){ + if (file == null) { return; } final FileEditorManagerEx editorManager = FileEditorManagerEx.getInstanceEx(myProject); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java index 35aceb5940a1..5bd2ae4b5407 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java @@ -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. @@ -230,7 +230,7 @@ class TextEditorComponent extends JPanel implements DataProvider{ * @return whether the editor is valid or not */ boolean isEditorValid(){ - return myValid; + return myValid && !myEditor.isDisposed(); } /** diff --git a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java index f9246c0edab1..0d60ed6689a2 100644 --- a/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java +++ b/platform/platform-impl/src/com/intellij/platform/PlatformProjectOpenProcessor.java @@ -16,6 +16,8 @@ package com.intellij.platform; import com.intellij.conversion.ConversionResult; + +import com.intellij.ide.GeneralSettings; import com.intellij.ide.impl.ProjectUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; @@ -125,10 +127,10 @@ public class PlatformProjectOpenProcessor extends ProjectOpenProcessor { } else { int exitCode = ProjectUtil.confirmOpenNewProject(false); - if (exitCode == 0) { // this window option + if (exitCode == GeneralSettings.OPEN_PROJECT_SAME_WINDOW) { if (!ProjectUtil.closeAndDispose(projectToClose)) return null; } - else if (exitCode != 1) { // not in a new window + else if (exitCode != GeneralSettings.OPEN_PROJECT_NEW_WINDOW) { // not in a new window return null; } } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java index ea7bbad563c4..0347e6ea21a2 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java @@ -137,6 +137,13 @@ public class MacMainFrameDecorator implements UISettingsListener, Disposable { if (window1 instanceof JFrame) { ID w = MacUtil.findWindowForTitle(((JFrame)window1).getTitle()); if (w != null && w.intValue() > 0) { + try { + Thread.sleep(300); + } + catch (InterruptedException e1) { + // ignore + } + invoke(w, "setCollectionBehavior:", 1 << 7); } } diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index a7de001cb4e9..0e0bbdb3c1df 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -16,6 +16,7 @@ package com.intellij.usages; import com.intellij.injected.editor.DocumentWindow; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lexer.Lexer; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -29,6 +30,7 @@ import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter; import com.intellij.openapi.fileTypes.SyntaxHighlighter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Segment; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; @@ -96,7 +98,7 @@ public class ChunkExtractor { }; public static TextChunk[] extractChunks(@NotNull PsiFile file, UsageInfo2UsageAdapter usageAdapter) { - return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter); + return ourExtractors.get().getValue().get(file).extractChunks(usageAdapter, file); } @@ -124,7 +126,7 @@ public class ChunkExtractor { return minStart == Integer.MAX_VALUE ? -1 : minStart; } - private TextChunk[] extractChunks(UsageInfo2UsageAdapter usageInfo2UsageAdapter) { + private TextChunk[] extractChunks(@NotNull UsageInfo2UsageAdapter usageInfo2UsageAdapter, @NotNull PsiFile file) { int absoluteStartOffset = usageInfo2UsageAdapter.getNavigationOffset(); if (absoluteStartOffset == -1) return TextChunk.EMPTY_ARRAY; @@ -150,6 +152,14 @@ public class ChunkExtractor { lineStartOffset = Math.max(lineStartOffset, absoluteStartOffset - OFFSET_BEFORE_TO_SHOW_WHEN_LONG_LINE); lineEndOffset = Math.min(lineEndOffset, absoluteStartOffset + OFFSET_AFTER_TO_SHOW_WHEN_LONG_LINE); } + if (myDocument instanceof DocumentWindow) { + List editable = InjectedLanguageManager.getInstance(file.getProject()) + .intersectWithAllEditableFragments(file, new TextRange(lineStartOffset, lineEndOffset)); + for (TextRange range : editable) { + createTextChunks(usageInfo2UsageAdapter, chars, range.getStartOffset(), range.getEndOffset(), result); + } + return result.toArray(new TextChunk[result.size()]); + } return createTextChunks(usageInfo2UsageAdapter, chars, lineStartOffset, lineEndOffset, result); } diff --git a/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java b/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java index 8664790af20d..cf3fb2747e13 100644 --- a/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java +++ b/platform/util/src/com/intellij/ui/mac/foundation/MacUtil.java @@ -18,6 +18,7 @@ package com.intellij.ui.mac.foundation; import org.jetbrains.annotations.Nullable; import javax.swing.*; + import java.awt.*; import static com.intellij.ui.mac.foundation.Foundation.invoke; @@ -67,12 +68,12 @@ public class MacUtil { return focusedWindow; } - public static synchronized void startModal(JComponent component) { + public static synchronized void startModal(JComponent component, String key) { try { if (SwingUtilities.isEventDispatchThread()) { EventQueue theQueue = component.getToolkit().getSystemEventQueue(); - while (component.getClientProperty(MAC_NATIVE_WINDOW_SHOWING) == Boolean.TRUE) { + while (component.getClientProperty(key) == Boolean.TRUE) { AWTEvent event = theQueue.getNextEvent(); Object source = event.getSource(); if (event instanceof ActiveEvent) { @@ -91,7 +92,7 @@ public class MacUtil { } else { assert false: "Should be called from Event-Dispatch Thread only!"; - while (component.getClientProperty(MAC_NATIVE_WINDOW_SHOWING) == Boolean.TRUE) { + while (component.getClientProperty(key) == Boolean.TRUE) { // TODO: //wait(); } @@ -101,5 +102,9 @@ public class MacUtil { } } + public static synchronized void startModal(JComponent component) { + startModal(component, MAC_NATIVE_WINDOW_SHOWING); + } + } diff --git a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java index 836dfb362a4f..4c2f09049869 100644 --- a/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java +++ b/plugins/android/src/org/jetbrains/android/newProject/AndroidModuleBuilder.java @@ -307,6 +307,20 @@ public class AndroidModuleBuilder extends JavaModuleBuilder { createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_ASSETS); createChildDirectoryIfNotExist(project, contentRoot, SdkConstants.FD_NATIVE_LIBS); } + else if (myProjectType == ProjectType.LIBRARY && myPackageName != null) { + final String[] dirs = myPackageName.split("\\."); + VirtualFile file = sourceRoot; + + for (String dir : dirs) { + if (file == null || dir.length() == 0) { + break; + } + final VirtualFile childDir = file.findChild(dir); + file = childDir != null + ? childDir + : file.createChildDirectory(project, dir); + } + } } catch (IOException e) { LOG.error(e); diff --git a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationEditor.java b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationEditor.java index 88b7d5df48a6..4c24b71a6a4b 100644 --- a/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationEditor.java +++ b/plugins/android/src/org/jetbrains/android/run/AndroidRunConfigurationEditor.java @@ -27,6 +27,7 @@ import com.intellij.openapi.util.Disposer; import com.intellij.ui.PanelWithAnchor; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.components.JBLabel; +import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -73,7 +74,16 @@ public class AndroidRunConfigurationEditor select(PsiElement e, CharSequence editorText, int cursorOffset, Editor editor) { List result = super.select(e, editorText, cursorOffset, editor); - if (e instanceof GrListOrMap) { - return result; - } + if (e instanceof GrListOrMap) return result; int startOffset = -1; int endOffset = -1; final String text = e.getText(); final int stringOffset = e.getTextOffset(); - if (e.getNode().getElementType() == mGSTRING_CONTENT) { + final IElementType elementType = e.getNode().getElementType(); + if (elementType == mGSTRING_CONTENT || elementType == mREGEX_CONTENT || elementType == mDOLLAR_SLASH_REGEX_CONTENT) { int cur; int index = -1; while (true) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyWordSelectionFilter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyWordSelectionFilter.java index 2d9ed0a0db22..a9e0530ebbe1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyWordSelectionFilter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyWordSelectionFilter.java @@ -19,12 +19,13 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; +import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; + /** * @author Maxim.Medvedev */ @@ -46,7 +47,9 @@ public class GroovyWordSelectionFilter implements Condition { type == mREGEX_BEGIN || type == mREGEX_CONTENT || type == mREGEX_END || - type == mWRONG_REGEX_LITERAL) { + type == mDOLLAR_SLASH_REGEX_BEGIN || + type == mDOLLAR_SLASH_REGEX_CONTENT || + type == mDOLLAR_SLASH_REGEX_END) { return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java index ff566957102b..4fe8253617cd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/DefaultHighlighter.java @@ -49,8 +49,6 @@ public class DefaultHighlighter { @NonNls static final String STRING_ID = "String"; @NonNls - static final String REGEXP_ID = "Regular expression"; - @NonNls static final String BRACES_ID = "Braces"; @NonNls static final String BRACKETS_ID = "Brackets"; @@ -150,9 +148,6 @@ public class DefaultHighlighter { public static TextAttributesKey STRING = TextAttributesKey.createTextAttributesKey(STRING_ID, SyntaxHighlighterColors.STRING.getDefaultAttributes()); - public static TextAttributesKey REGEXP = TextAttributesKey.createTextAttributesKey(REGEXP_ID, - SyntaxHighlighterColors.VALID_STRING_ESCAPE.getDefaultAttributes()); - public static TextAttributesKey BRACES = TextAttributesKey.createTextAttributesKey(BRACES_ID, SyntaxHighlighterColors.BRACES.getDefaultAttributes()); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyBraceMatcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyBraceMatcher.java index afb6fb98d793..b00587a4cc70 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyBraceMatcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyBraceMatcher.java @@ -19,14 +19,18 @@ package org.jetbrains.plugins.groovy.highlighter; import com.intellij.lang.BracePair; import com.intellij.lang.PairedBraceMatcher; import com.intellij.psi.PsiFile; -import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.GroovyFileType; -import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; -import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; + +import static com.intellij.psi.TokenType.WHITE_SPACE; +import static org.jetbrains.plugins.groovy.GroovyFileType.GROOVY_LANGUAGE; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_END; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_INLINE_TAG_START; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_LPAREN; +import static org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes.mGDOC_TAG_VALUE_RPAREN; +import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; +import static org.jetbrains.plugins.groovy.lang.lexer.TokenSets.COMMENT_SET; /** * Brace matcher for Groovy language @@ -36,32 +40,35 @@ import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; public class GroovyBraceMatcher implements PairedBraceMatcher { private static final BracePair[] PAIRS = { - new BracePair(GroovyTokenTypes.mLPAREN, GroovyTokenTypes.mRPAREN, false), - new BracePair(GroovyTokenTypes.mLBRACK, GroovyTokenTypes.mRBRACK, false), - new BracePair(GroovyTokenTypes.mLCURLY, GroovyTokenTypes.mRCURLY, true), + new BracePair(mLPAREN, mRPAREN, false), + new BracePair(mLBRACK, mRBRACK, false), + new BracePair(mLCURLY, mRCURLY, true), - new BracePair(GroovyDocTokenTypes.mGDOC_INLINE_TAG_START, GroovyDocTokenTypes.mGDOC_INLINE_TAG_END, true), - new BracePair(GroovyDocTokenTypes.mGDOC_TAG_VALUE_LPAREN, GroovyDocTokenTypes.mGDOC_TAG_VALUE_RPAREN, false), + new BracePair(mGDOC_INLINE_TAG_START, mGDOC_INLINE_TAG_END, true), + new BracePair(mGDOC_TAG_VALUE_LPAREN, mGDOC_TAG_VALUE_RPAREN, false), - new BracePair(GroovyTokenTypes.mGSTRING_BEGIN, GroovyTokenTypes.mGSTRING_END, false), - new BracePair(GroovyTokenTypes.mREGEX_BEGIN, GroovyTokenTypes.mREGEX_END, false) + new BracePair(mGSTRING_BEGIN, mGSTRING_END, false), + new BracePair(mREGEX_BEGIN, mREGEX_END, false), + new BracePair(mDOLLAR_SLASH_REGEX_BEGIN, mDOLLAR_SLASH_REGEX_END, false), }; public BracePair[] getPairs() { return PAIRS; } - public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType ibraceType, @Nullable IElementType tokenType) { + public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType braceType, @Nullable IElementType tokenType) { return tokenType == null - || TokenType.WHITE_SPACE == tokenType - || TokenSets.COMMENT_SET.contains(tokenType) - || tokenType == GroovyTokenTypes.mSEMI - || tokenType == GroovyTokenTypes.mCOMMA - || tokenType == GroovyTokenTypes.mRPAREN - || tokenType == GroovyTokenTypes.mRBRACK - || tokenType == GroovyTokenTypes.mRCURLY - || tokenType == GroovyTokenTypes.mGSTRING_BEGIN - || tokenType.getLanguage() != GroovyFileType.GROOVY_LANGUAGE; + || tokenType == WHITE_SPACE + || tokenType == mSEMI + || tokenType == mCOMMA + || tokenType == mRPAREN + || tokenType == mRBRACK + || tokenType == mRCURLY + || tokenType == mGSTRING_BEGIN + || tokenType == mREGEX_BEGIN + || tokenType == mDOLLAR_SLASH_REGEX_BEGIN + || COMMENT_SET.contains(tokenType) + || tokenType.getLanguage() != GROOVY_LANGUAGE; } public int getCodeConstructStart(PsiFile file, int openingBraceOffset) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java index 358a9c072016..bd6bbb63d9ab 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovyColorsAndFontsPage.java @@ -58,7 +58,6 @@ public class GroovyColorsAndFontsPage implements ColorSettingsPage { new AttributesDescriptor("Number", DefaultHighlighter.NUMBER), new AttributesDescriptor("GString", DefaultHighlighter.GSTRING), new AttributesDescriptor("String", DefaultHighlighter.STRING), - new AttributesDescriptor("Regular expression", DefaultHighlighter.REGEXP), new AttributesDescriptor("Braces", DefaultHighlighter.BRACES), new AttributesDescriptor("Brackets", DefaultHighlighter.BRACKETS), new AttributesDescriptor("Parentheses", DefaultHighlighter.PARENTHESES), diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java new file mode 100644 index 000000000000..82ef61fa447b --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySlashyStringLexer.java @@ -0,0 +1,98 @@ +/* + * 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. + */ +package org.jetbrains.plugins.groovy.highlighter; + +import com.intellij.lexer.LexerBase; +import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; + +/** + * @author Max Medvedev + */ +public class GroovySlashyStringLexer extends LexerBase { + private CharSequence myBuffer; + private int myStart; + private int myBufferEnd; + private IElementType myTokenType; + private int myEnd; + + + public GroovySlashyStringLexer() { + } + + @Override + public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) { + myBuffer = buffer; + myEnd = startOffset; + myBufferEnd = endOffset; + myTokenType = locateToken(); + } + + @Nullable + private IElementType locateToken() { + if (myEnd >= myBufferEnd) return null; + + myStart = myEnd; + if (checkForEscape(myStart)) { + myEnd = myStart + 2; + return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN; + } + + while (myEnd < myBufferEnd && !checkForEscape(myEnd)) myEnd++; + return GroovyTokenTypes.mREGEX_CONTENT; + } + + private boolean checkForEscape(int start) { + return myBuffer.charAt(start) == '\\' && start + 1 < myBufferEnd && myBuffer.charAt(start + 1) == '/'; + } + + @Override + public int getState() { + return 0; + } + + @Override + public IElementType getTokenType() { + return myTokenType; + } + + @Override + public int getTokenStart() { + return myStart; + } + + @Override + public int getTokenEnd() { + return myEnd; + } + + @Override + public void advance() { + myTokenType = locateToken(); + } + + @Override + public CharSequence getBufferSequence() { + return myBuffer; + } + + @Override + public int getBufferEnd() { + return myBufferEnd; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySyntaxHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySyntaxHighlighter.java index fea08fc87d88..98c94e263715 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySyntaxHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/highlighter/GroovySyntaxHighlighter.java @@ -62,10 +62,6 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr mWRONG ); - static final TokenSet tWRONG_REGEX = TokenSet.create( - mWRONG_REGEX_LITERAL - ); - static final TokenSet tGSTRINGS = TokenSet.create( mGSTRING_BEGIN, mGSTRING_CONTENT, @@ -77,15 +73,6 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr mSTRING_LITERAL ); - static final TokenSet tREGEXP = TokenSet.create( - mREGEX_LITERAL, - - mREGEX_BEGIN, - mREGEX_CONTENT, - mREGEX_END - - ); - static final TokenSet tBRACES = TokenSet.create( mLCURLY, mRCURLY @@ -210,8 +197,7 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr fillMap(ATTRIBUTES, tNUMBERS, DefaultHighlighter.NUMBER); fillMap(ATTRIBUTES, tGSTRINGS, DefaultHighlighter.GSTRING); fillMap(ATTRIBUTES, tSTRINGS, DefaultHighlighter.STRING); - fillMap(ATTRIBUTES, tREGEXP, DefaultHighlighter.REGEXP); - fillMap(ATTRIBUTES, tWRONG_REGEX, DefaultHighlighter.REGEXP); + fillMap(ATTRIBUTES, DefaultHighlighter.STRING, mREGEX_BEGIN, mREGEX_CONTENT, mREGEX_END, mDOLLAR_SLASH_REGEX_BEGIN, mDOLLAR_SLASH_REGEX_CONTENT, mDOLLAR_SLASH_REGEX_END); fillMap(ATTRIBUTES, tBRACES, DefaultHighlighter.BRACES); fillMap(ATTRIBUTES, tBRACKETS, DefaultHighlighter.BRACKETS); fillMap(ATTRIBUTES, tPARENTHESES, DefaultHighlighter.PARENTHESES); @@ -234,6 +220,8 @@ public class GroovySyntaxHighlighter extends SyntaxHighlighterBase implements Gr new IElementType[]{GroovyTokenTypes.mGSTRING_LITERAL}, IElementType.EMPTY_ARRAY); registerSelfStoppingLayer(new StringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, GroovyTokenTypes.mGSTRING_CONTENT, true, "$"), new IElementType[]{GroovyTokenTypes.mGSTRING_CONTENT}, IElementType.EMPTY_ARRAY); + registerSelfStoppingLayer(new GroovySlashyStringLexer(), new IElementType[]{GroovyTokenTypes.mREGEX_CONTENT}, + IElementType.EMPTY_ARRAY); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java index 015a357c4cdf..db50abfabe87 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/editor/GroovyLiteralCopyPasteProcessor.java @@ -111,10 +111,7 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce protected String escapeCharCharacters(@NotNull String s, @NotNull PsiElement token, boolean escapeSlashes) { IElementType tokenType = token.getNode().getElementType(); - if (tokenType == mREGEX_CONTENT || - tokenType == mREGEX_LITERAL || - tokenType == mDOLLAR_SLASH_REGEX_CONTENT || - tokenType == mDOLLAR_SLASH_REGEX_LITERAL) { + if (tokenType == mREGEX_CONTENT || tokenType == mDOLLAR_SLASH_REGEX_CONTENT) { if (escapeSlashes) { return StringUtil.escapeSlashes(s); } @@ -149,10 +146,7 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce protected String unescape(String text, PsiElement token) { final IElementType tokenType = token.getNode().getElementType(); - if (tokenType == mREGEX_CONTENT || - tokenType == mREGEX_LITERAL || - tokenType == mDOLLAR_SLASH_REGEX_CONTENT || - tokenType == mDOLLAR_SLASH_REGEX_LITERAL) { + if (tokenType == mREGEX_CONTENT || tokenType == mDOLLAR_SLASH_REGEX_CONTENT) { return StringUtil.unescapeSlashes(text); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/GroovyTokenTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/GroovyTokenTypes.java index 06ab7b56226e..65489558aed4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/GroovyTokenTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/GroovyTokenTypes.java @@ -73,10 +73,6 @@ public interface GroovyTokenTypes extends GroovyDocElementTypes { IElementType mGSTRING_CONTENT = new GroovyElementType("Gstring content"); IElementType mGSTRING_END = new GroovyElementType("Gstring end"); - IElementType mREGEX_LITERAL = new GroovyElementType("regexp"); - IElementType mDOLLAR_SLASH_REGEX_LITERAL = new GroovyElementType("$/ regexp"); - IElementType mWRONG_DOLLAR_SLASH_LITERAL = new GroovyElementType("wrong dollar slash literal"); - IElementType mREGEX_BEGIN = new GroovyElementType("regex begin"); IElementType mREGEX_CONTENT = new GroovyElementType("regex content"); IElementType mREGEX_END = new GroovyElementType("regex end"); @@ -85,9 +81,6 @@ public interface GroovyTokenTypes extends GroovyDocElementTypes { IElementType mDOLLAR_SLASH_REGEX_CONTENT = new GroovyElementType("$/ regex content"); IElementType mDOLLAR_SLASH_REGEX_END = new GroovyElementType("$/ regex end"); - IElementType mWRONG_REGEX_LITERAL = new GroovyElementType("wrong regex"); - IElementType mWRONG_DOLLAR_SLASH_REGEX_LITERAL = new GroovyElementType("wrong $/ regex"); - /* ************************************************************************************************** * Common tokens: operators, braces etc. * ****************************************************************************************************/ diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java index 93710d76d299..623b870704e7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/lexer/TokenSets.java @@ -68,9 +68,7 @@ public abstract class TokenSets { kFALSE, kNULL, mSTRING_LITERAL, - mGSTRING_LITERAL, - mREGEX_LITERAL, - mDOLLAR_SLASH_REGEX_LITERAL + mGSTRING_LITERAL ); public static final TokenSet BUILT_IN_TYPE = TokenSet.create( @@ -123,10 +121,8 @@ public abstract class TokenSets { public static TokenSet STRING_LITERALS = TokenSet.create( mSTRING_LITERAL, - mREGEX_LITERAL, mREGEX_CONTENT, mDOLLAR_SLASH_REGEX_CONTENT, - mDOLLAR_SLASH_REGEX_LITERAL, mGSTRING_LITERAL, mGSTRING_CONTENT, mGSTRING_BEGIN, diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java index ffe41c5501ad..222564b51b1d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java @@ -115,11 +115,12 @@ public class ArgumentList implements GroovyElementTypes { marker.done(ARGUMENT_LABEL); return true; } - else if (ParserUtils.lookAhead(builder, mIDENT, mCOLON) || - TokenSets.KEYWORDS.contains(builder.getTokenType()) || - mSTRING_LITERAL.equals(builder.getTokenType()) || - mGSTRING_LITERAL.equals(builder.getTokenType()) || - mREGEX_LITERAL.equals(builder.getTokenType())) { + + final IElementType type = builder.getTokenType(); + if (ParserUtils.lookAhead(builder, mIDENT, mCOLON) || + TokenSets.KEYWORDS.contains(type) || + mSTRING_LITERAL.equals(type) || + mGSTRING_LITERAL.equals(type)) { builder.advanceLexer(); if (mCOLON.equals(builder.getTokenType())) { marker.done(ARGUMENT_LABEL); @@ -130,12 +131,14 @@ public class ArgumentList implements GroovyElementTypes { return false; } } - else if (mGSTRING_BEGIN.equals(builder.getTokenType()) || - mREGEX_BEGIN.equals(builder.getTokenType()) || - TokenSets.NUMBERS.contains(builder.getTokenType()) || - mLBRACK.equals(builder.getTokenType()) || - mLPAREN.equals(builder.getTokenType()) || - mLCURLY.equals(builder.getTokenType())) { + + if (mGSTRING_BEGIN.equals(type) || + mREGEX_BEGIN.equals(type) || + mDOLLAR_SLASH_REGEX_BEGIN.equals(type) || + TokenSets.NUMBERS.contains(type) || + mLBRACK.equals(type) || + mLPAREN.equals(type) || + mLCURLY.equals(type)) { PrimaryExpression.parsePrimaryExpression(builder, parser); if (mCOLON.equals(builder.getTokenType())) { marker.done(ARGUMENT_LABEL); @@ -146,11 +149,8 @@ public class ArgumentList implements GroovyElementTypes { return false; } } - else { - marker.drop(); - return false; - } + marker.drop(); + return false; } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java index 4125cb347519..45500d00a401 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java @@ -26,6 +26,7 @@ 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.blocks.OpenOrClosableBlock; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.ArgumentList; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.DollarSlashRegexConstructorExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.PrimaryExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.RegexConstructorExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.StringConstructorExpression; @@ -227,17 +228,15 @@ public class PathExpression implements GroovyElementTypes { } final IElementType tokenType = builder.getTokenType(); - if (mREGEX_LITERAL.equals(tokenType)) { - ParserUtils.eatElement(builder, REGEX); - return PATH_PROPERTY_REFERENCE; - } if (mGSTRING_BEGIN.equals(tokenType)) { StringConstructorExpression.parse(builder, parser); return PATH_PROPERTY_REFERENCE; } if (mREGEX_BEGIN.equals(tokenType)) { - RegexConstructorExpression.parse(builder, parser); - return PATH_PROPERTY_REFERENCE; + return RegexConstructorExpression.parse(builder, parser) ? PATH_PROPERTY_REFERENCE : REFERENCE_EXPRESSION; + } + if (mDOLLAR_SLASH_REGEX_BEGIN.equals(tokenType)) { + return DollarSlashRegexConstructorExpression.parse(builder, parser) ? PATH_PROPERTY_REFERENCE : REFERENCE_EXPRESSION; } if (mLCURLY.equals(tokenType)) { OpenOrClosableBlock.parseOpenBlock(builder, parser); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/DollarSlashRegexConstructorExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/DollarSlashRegexConstructorExpression.java index d719090cca4e..3a745d324708 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/DollarSlashRegexConstructorExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/DollarSlashRegexConstructorExpression.java @@ -16,52 +16,40 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary; import com.intellij.lang.PsiBuilder; +import com.intellij.openapi.diagnostic.Logger; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.PathExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mDOLLAR; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mDOLLAR_SLASH_REGEX_BEGIN; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mDOLLAR_SLASH_REGEX_CONTENT; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mDOLLAR_SLASH_REGEX_END; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mIDENT; -import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mLCURLY; -import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.*; +import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.GSTRING_INJECTION; +import static org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes.REGEX; /** * @author Max Medvedev */ public class DollarSlashRegexConstructorExpression { - public static GroovyElementType parse(PsiBuilder builder, GroovyParser parser) { + private static final Logger LOG = Logger.getInstance(DollarSlashRegexConstructorExpression.class); - PsiBuilder.Marker sMarker = builder.mark(); - if (ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_BEGIN)) { + public static boolean parse(PsiBuilder builder, GroovyParser parser) { + PsiBuilder.Marker marker = builder.mark(); + final boolean result = ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_BEGIN); + LOG.assertTrue(result); + + boolean inj = false; + ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_CONTENT); + while (parseInjection(builder, parser)) { + inj = true; ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_CONTENT); - if (!parseInjection(builder, parser)) { - if (!ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_END)) { - builder.error(GroovyBundle.message("dollar.slash.end.expected")); - } - sMarker.done(REGEX); - return REGEX; - } - else { - while (ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_CONTENT)) { - if (!parseInjection(builder, parser)) break; - } - if (!ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_END)) { - builder.error(GroovyBundle.message("dollar.slash.end.expected")); - } - sMarker.done(REGEX); - return REGEX; - } } - else { - sMarker.drop(); - return WRONGWAY; + + if (!ParserUtils.getToken(builder, mDOLLAR_SLASH_REGEX_END)) { + builder.error(GroovyBundle.message("dollar.slash.end.expected")); } + marker.done(REGEX); + return inj; } /** diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java index 49a5ebaa0b44..eb04353f7a2f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java @@ -69,10 +69,12 @@ public class PrimaryExpression implements GroovyElementTypes { return StringConstructorExpression.parse(builder, parser); } if (mREGEX_BEGIN == tokenType) { - return RegexConstructorExpression.parse(builder, parser); + RegexConstructorExpression.parse(builder, parser); + return REGEX; } if (mDOLLAR_SLASH_REGEX_BEGIN == tokenType) { - return DollarSlashRegexConstructorExpression.parse(builder, parser); + DollarSlashRegexConstructorExpression.parse(builder, parser); + return REGEX; } if (mLBRACK == tokenType) { return ListOrMapConstructorExpression.parse(builder, parser); @@ -83,31 +85,12 @@ public class PrimaryExpression implements GroovyElementTypes { if (mLCURLY == tokenType) { return OpenOrClosableBlock.parseClosableBlock(builder, parser); } - if (tokenType == mSTRING_LITERAL || - tokenType == mGSTRING_LITERAL || - tokenType == mREGEX_LITERAL || - tokenType == mDOLLAR_SLASH_REGEX_LITERAL) { + if (tokenType == mSTRING_LITERAL || tokenType == mGSTRING_LITERAL) { return ParserUtils.eatElement(builder, literalsAsRefExprs ? REFERENCE_EXPRESSION : LITERAL); } if (TokenSets.CONSTANTS.contains(tokenType)) { return ParserUtils.eatElement(builder, LITERAL); } - if (mWRONG_REGEX_LITERAL == tokenType) { - PsiBuilder.Marker marker = builder.mark(); - builder.advanceLexer(); - builder.error(GroovyBundle.message("regex.end.expected")); - marker.done(LITERAL); - return LITERAL; - } - if (mWRONG_DOLLAR_SLASH_LITERAL == tokenType) { - final PsiBuilder.Marker marker = builder.mark(); - builder.advanceLexer(); - builder.error(GroovyBundle.message("dollar.slash.end.expected")); - marker.done(LITERAL); - return LITERAL; - } - - // TODO implement all cases! return WRONGWAY; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/RegexConstructorExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/RegexConstructorExpression.java index d453fa433af0..b74b218412a9 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/RegexConstructorExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/RegexConstructorExpression.java @@ -17,8 +17,8 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary; import com.intellij.lang.PsiBuilder; +import com.intellij.openapi.diagnostic.Logger; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; 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.blocks.OpenOrClosableBlock; @@ -29,34 +29,28 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; * @author ilyas */ public class RegexConstructorExpression implements GroovyElementTypes { + private static final Logger LOG = Logger.getInstance(RegexConstructorExpression.class); - public static GroovyElementType parse(PsiBuilder builder, GroovyParser parser) { + /** + * @return true if there are any injections + */ + public static boolean parse(PsiBuilder builder, GroovyParser parser) { + PsiBuilder.Marker marker = builder.mark(); + final boolean result = ParserUtils.getToken(builder, mREGEX_BEGIN); + LOG.assertTrue(result); - PsiBuilder.Marker sMarker = builder.mark(); - if (ParserUtils.getToken(builder, mREGEX_BEGIN)) { + boolean inj = false; + ParserUtils.getToken(builder, mREGEX_CONTENT); + while (parseInjection(builder, parser)) { + inj = true; ParserUtils.getToken(builder, mREGEX_CONTENT); - if (!parseInjection(builder, parser)) { - if (!ParserUtils.getToken(builder, mREGEX_END)) { - builder.error(GroovyBundle.message("regex.end.expected")); - } - sMarker.done(REGEX); - return REGEX; - } - else { - while (ParserUtils.getToken(builder, mREGEX_CONTENT)) { - if (!parseInjection(builder, parser)) break; - } - if (!ParserUtils.getToken(builder, mREGEX_END)) { - builder.error(GroovyBundle.message("regex.end.expected")); - } - sMarker.done(REGEX); - return REGEX; - } } - else { - sMarker.drop(); - return WRONGWAY; + + if (!ParserUtils.getToken(builder, mREGEX_END)) { + builder.error(GroovyBundle.message("regex.end.expected")); } + marker.done(REGEX); + return inj; } /** diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrPropertySelectionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrPropertySelectionImpl.java index 0cc928b8e0d5..0e35dbef859f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrPropertySelectionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrPropertySelectionImpl.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path; import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; @@ -30,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer * @author ilyas */ public class GrPropertySelectionImpl extends GrReferenceExpressionImpl implements GrPropertySelection { + private static final Logger LOG = Logger.getInstance(GrPropertySelectionImpl.class); public GrPropertySelectionImpl(@NotNull ASTNode node) { super(node); @@ -70,7 +72,7 @@ public class GrPropertySelectionImpl extends GrReferenceExpressionImpl implement @Override public PsiElement getReferenceNameElement() { final PsiElement last = getLastChild(); - assert last != null; + LOG.assertTrue(last!=null); return last; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/ExpressionsParsingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/ExpressionsParsingTest.groovy index 7a3d0255e208..978360b13604 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/ExpressionsParsingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/ExpressionsParsingTest.groovy @@ -133,6 +133,7 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase { public void testpath$path8() throws Throwable { doTest(); } public void testpath$path9() throws Throwable { doTest(); } public void testpath$path10() throws Throwable {doTest(); } + public void testpath$regexp() {doTest()} public void testpath$typeVsExpr() {doTest();} public void testreferences$ref1() throws Throwable { doTest(); } public void testreferences$ref2() throws Throwable { doTest(); } @@ -159,6 +160,8 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase { public void testregex$regex2() throws Throwable { doTest(); } public void testregex$regex20() throws Throwable { doTest(); } public void testregex$regex21() throws Throwable { doTest(); } + public void testregex$regex22() throws Throwable { doTest(); } + public void testregex$regex23() throws Throwable { doTest(); } public void testregex$regex3() throws Throwable { doTest(); } public void testregex$regex33() throws Throwable { doTest(); } public void testregex$regex4() throws Throwable { doTest(); } diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test b/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test new file mode 100644 index 000000000000..330bf7ac6e3b --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/path/regexp.test @@ -0,0 +1,44 @@ +a.$/dfg/$./fg/."sfg"./${a}/.$/df$g/$ +----- +Groovy script + Property selection + Property selection + Reference expression + Reference expression + Reference expression + Reference expression + PsiElement(identifier)('a') + PsiElement(.)('.') + Compound regular expression + PsiElement($/ regex begin)('$/') + PsiElement($/ regex content)('dfg') + PsiElement($/ regex end)('/$') + PsiElement(.)('.') + Compound regular expression + PsiElement(regex begin)('/') + PsiElement(regex content)('fg') + PsiElement(regex end)('/') + PsiElement(.)('.') + PsiElement(Gstring)('"sfg"') + PsiElement(.)('.') + Compound regular expression + PsiElement(regex begin)('/') + GString injection + PsiElement($)('$') + Closable block + PsiElement({)('{') + Parameter list + + Reference expression + PsiElement(identifier)('a') + PsiElement(})('}') + PsiElement(regex end)('/') + PsiElement(.)('.') + Compound regular expression + PsiElement($/ regex begin)('$/') + PsiElement($/ regex content)('df') + GString injection + PsiElement($)('$') + Reference expression + PsiElement(identifier)('g') + PsiElement($/ regex end)('/$') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test index f0989133fb9d..d7802962bb1d 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex10.test @@ -36,7 +36,7 @@ Groovy script Parameter list Method call - Property selection + Reference expression Reference expression PsiElement(identifier)('frg') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test new file mode 100644 index 000000000000..f13ddd70ad61 --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex22.test @@ -0,0 +1,24 @@ +/${1}${2}/ +----- +Groovy script + Compound regular expression + PsiElement(regex begin)('/') + GString injection + PsiElement($)('$') + Closable block + PsiElement({)('{') + Parameter list + + Literal + PsiElement(Integer)('1') + PsiElement(})('}') + GString injection + PsiElement($)('$') + Closable block + PsiElement({)('{') + Parameter list + + Literal + PsiElement(Integer)('2') + PsiElement(})('}') + PsiElement(regex end)('/') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test new file mode 100644 index 000000000000..00e27cd6ae22 --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex23.test @@ -0,0 +1,24 @@ +$/${1}${2}/$ +----- +Groovy script + Compound regular expression + PsiElement($/ regex begin)('$/') + GString injection + PsiElement($)('$') + Closable block + PsiElement({)('{') + Parameter list + + Literal + PsiElement(Integer)('1') + PsiElement(})('}') + GString injection + PsiElement($)('$') + Closable block + PsiElement({)('{') + Parameter list + + Literal + PsiElement(Integer)('2') + PsiElement(})('}') + PsiElement($/ regex end)('/$') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test index 2f289315bb04..601e09b3cd4c 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex8.test @@ -52,7 +52,7 @@ Groovy script Parameter list Method call - Property selection + Reference expression Reference expression PsiElement(identifier)('frg') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test index 8a222ba86109..14231157069a 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/regex/regex9.test @@ -53,7 +53,7 @@ Groovy script Parameter list Method call - Property selection + Reference expression Reference expression PsiElement(identifier)('frg') PsiElement(.)('.')