Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2017-11-27 16:34:19 +01:00
27 changed files with 149 additions and 272 deletions
+4 -3
View File
@@ -1,11 +1,12 @@
<component name="libraryTable">
<library name="ini4j">
<library name="ini4j" type="repository">
<properties maven-id="org.jetbrains.intellij.deps:ini4j:0.5.5-1" />
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/ini4j-0.5.2-patched.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/ini4j/0.5.5-1/ini4j-0.5.5-1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/ini4j-0.5.2-patched-sources.zip!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/ini4j/0.5.5-1/ini4j-0.5.5-1-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -51,17 +51,15 @@ import java.util.*;
*/
public class ArtifactRepositoryManager {
private static final VersionScheme ourVersioning = new GenericVersionScheme();
private static final JreProxySelector ourProxySelector = new JreProxySelector();
private final DefaultRepositorySystemSession mySession;
public static final RemoteRepository MAVEN_CENTRAL_REPOSITORY = createRemoteRepository(
private static final RemoteRepository MAVEN_CENTRAL_REPOSITORY = createRemoteRepository(
"central", "http://repo1.maven.org/maven2/"
);
public static final RemoteRepository JBOSS_COMMUNITY_REPOSITORY = createRemoteRepository(
private static final RemoteRepository JBOSS_COMMUNITY_REPOSITORY = createRemoteRepository(
"jboss.community", "https://repository.jboss.org/nexus/content/repositories/public/"
);
public static final List<RemoteRepository> PREDEFINED_REMOTE_REPOSITORIES = Collections.unmodifiableList(Arrays.asList(
MAVEN_CENTRAL_REPOSITORY, JBOSS_COMMUNITY_REPOSITORY
));
private static final RepositorySystem ourSystem;
static {
@@ -86,7 +84,8 @@ public class ArtifactRepositoryManager {
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath, @NotNull final ProgressConsumer progressConsumer) {
this(localRepositoryPath, PREDEFINED_REMOTE_REPOSITORIES, progressConsumer);
// recreate remote repository objects to ensure the latest proxy settings are used
this(localRepositoryPath, Arrays.asList(createRemoteRepository(MAVEN_CENTRAL_REPOSITORY), createRemoteRepository(JBOSS_COMMUNITY_REPOSITORY)), progressConsumer);
}
public ArtifactRepositoryManager(@NotNull File localRepositoryPath, List<RemoteRepository> remoteRepositories, @NotNull final ProgressConsumer progressConsumer) {
@@ -115,7 +114,7 @@ public class ArtifactRepositoryManager {
// setup session here
session.setLocalRepositoryManager(ourSystem.newLocalRepositoryManager(session, new LocalRepository(localRepositoryPath)));
session.setProxySelector(new org.jetbrains.idea.maven.aether.JreProxySelector());
session.setProxySelector(ourProxySelector);
session.setReadOnly();
mySession = session;
}
@@ -202,7 +201,12 @@ public class ArtifactRepositoryManager {
public static RemoteRepository createRemoteRepository(final String id, final String url) {
// for maven repos repository type should be 'default'
return new RemoteRepository.Builder(id, "default", url).build();
return new RemoteRepository.Builder(id, "default", url).setProxy(ourProxySelector.getProxy(url)).build();
}
public static RemoteRepository createRemoteRepository(RemoteRepository prototype) {
final String url = prototype.getUrl();
return new RemoteRepository.Builder(prototype.getId(), prototype.getContentType(), url).setProxy(ourProxySelector.getProxy(url)).build();
}
private CollectRequest createCollectRequest(String groupId, String artifactId, Collection<VersionConstraint> versions, final Set<ArtifactKind> kinds) {
@@ -4,6 +4,7 @@ package org.jetbrains.idea.maven.aether;
import org.eclipse.aether.repository.*;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.ProxySelector;
import org.jetbrains.annotations.Nullable;
import java.net.*;
import java.util.List;
@@ -19,12 +20,17 @@ final class JreProxySelector implements ProxySelector {
}
public Proxy getProxy(RemoteRepository repository) {
return getProxy(repository.getUrl());
}
@Nullable
public Proxy getProxy(final String url) {
try {
final java.net.ProxySelector systemSelector = java.net.ProxySelector.getDefault();
if (systemSelector == null) {
return null;
}
final URI uri = new URI(repository.getUrl()).parseServerAuthority();
final URI uri = new URI(url).parseServerAuthority();
final List<java.net.Proxy> selected = systemSelector.select(uri);
if (selected == null || selected.isEmpty()) {
return null;
@@ -100,7 +100,8 @@ import org.jetbrains.jps.incremental.Utils;
import org.jetbrains.jps.model.java.JpsJavaSdkType;
import org.jetbrains.jps.model.java.compiler.JavaCompilers;
import javax.tools.*;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.awt.*;
import java.io.File;
import java.io.IOException;
@@ -249,8 +250,12 @@ public class BuildManager implements Disposable {
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
if (!IS_UNIT_TEST_MODE && shouldTriggerMake(events)) {
scheduleAutoMake();
if (!IS_UNIT_TEST_MODE) {
ApplicationManager.getApplication().executeOnPooledThread(() -> ReadAction.run(()->{
if (shouldTriggerMake(events)) {
scheduleAutoMake();
}
}));
}
}
Binary file not shown.
Binary file not shown.
@@ -25,15 +25,24 @@ public class IdeaForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWor
// must be called in the earliest possible moment on startup
public static void setupForkJoinCommonPool() {
System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", IdeaForkJoinWorkerThreadFactory.class.getName());
String explicitParallelism = System.getProperty("java.util.concurrent.ForkJoinPool.common.parallelism");
if (explicitParallelism == null && Runtime.getRuntime().availableProcessors() == 2) {
// By default FJP initialized with the parallelism=N_CPU - 1
// so in case of two processors it becomes parallelism=1 which is too unexpected.
// In this case force parallelism=2
System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "2");
}
}
private static final AtomicLong bits = new AtomicLong();
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
final int n = setNextBit();
//System.out.println("New FJP thread "+n);
ForkJoinWorkerThread thread = new ForkJoinWorkerThread(pool) {
@Override
protected void onTermination(Throwable exception) {
//System.out.println("Exit FJP thread "+n);
clearBit(n);
super.onTermination(exception);
}
@@ -146,8 +146,8 @@ class CommunityLibraryLicenses {
new LibraryLicense(name: "ImageIO", libraryName: "imageio-tiff", version: "3.2.1", license: "BSD",
url: "https://github.com/haraldk/TwelveMonkeys", licenseUrl: "https://github.com/haraldk/TwelveMonkeys#license"),
new LibraryLicense(name: "Inconsolata", attachedTo: "platform-resources", version: "001.010", license: "OFL", url: "https://github.com/google/fonts/blob/master/ofl/inconsolata/OFL.txt"),
new LibraryLicense(name: "ini4j", libraryName: "ini4j", version: "0.5.2 (with a patch by JetBrains)", license: "Apache 2.0",
url: "http://ini4j.sourceforge.net/", licenseUrl: "http://ini4j.sourceforge.net/license.html"),
new LibraryLicense(name: "ini4j (JetBrains's fork)", libraryName: "ini4j", version: "0.5.5-1", license: "Apache 2.0",
url: "https://github.com/JetBrains/intellij-deps-ini4j"),
new LibraryLicense(name: "ISO RELAX", libraryName: "isorelax.jar", license: "MIT License",
url: "http://sourceforge.net/projects/iso-relax/", licenseUrl: "http://www.opensource.org/licenses/mit-license.html"),
new LibraryLicense(name: "Jakarta ORO", libraryName: "OroMatcher", version: "2.0.8", license: "Apache",
@@ -23,6 +23,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
@@ -41,6 +42,8 @@ public abstract class InjectedLanguageManager {
protected static final NotNullLazyKey<InjectedLanguageManager, Project> INSTANCE_CACHE = ServiceManager.createLazyKey(InjectedLanguageManager.class);
public static final Key<Boolean> FRANKENSTEIN_INJECTION = Key.create("FRANKENSTEIN_INJECTION");
public abstract PsiLanguageInjectionHost getInjectionHost(@NotNull FileViewProvider provider);
public static InjectedLanguageManager getInstance(Project project) {
return INSTANCE_CACHE.getValue(project);
}
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.ElementManipulators;
@@ -34,7 +35,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.injected.Place;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ObjectUtils;
@@ -127,12 +127,12 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
}
public static QuickEditHandler getExistingHandler(@NotNull PsiFile injectedFile) {
Place shreds = InjectedLanguageUtil.getShreds(injectedFile);
DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
if (shreds == null || documentWindow == null) return null;
if (documentWindow == null) return null;
TextRange hostRange = TextRange.create(shreds.get(0).getHostRangeMarker().getStartOffset(),
shreds.get(shreds.size() - 1).getHostRangeMarker().getEndOffset());
Segment[] hostRanges = documentWindow.getHostRanges();
TextRange hostRange = TextRange.create(hostRanges[0].getStartOffset(),
hostRanges[hostRanges.length - 1].getEndOffset());
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
if (editor.getDocument() != documentWindow.getDelegate()) continue;
QuickEditHandler handler = editor.getUserData(QUICK_EDIT_HANDLER);
@@ -124,7 +124,8 @@ public class QuickEditHandler implements Disposable, DocumentListener {
// suppress possible errors as in injected mode
myNewFile.putUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION,
injectedFile.getUserData(InjectedLanguageUtil.FRANKENSTEIN_INJECTION));
myNewFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, shreds.getHostPointer());
PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(project).getInjectionHost(injectedFile.getViewProvider());
myNewFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, SmartPointerManager.getInstance(project).createSmartPsiElementPointer(host));
myNewDocument = PsiDocumentManager.getInstance(project).getDocument(myNewFile);
assert myNewDocument != null;
EditorActionManager.getInstance().setReadonlyFragmentModificationHandler(myNewDocument, new MyQuietHandler());
@@ -174,6 +174,12 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
}
}
@Override
public PsiLanguageInjectionHost getInjectionHost(@NotNull FileViewProvider provider) {
if (!(provider instanceof InjectedFileViewProvider)) return null;
return ((InjectedFileViewProvider)provider).getShreds().getHostPointer().getElement();
}
@Override
public PsiLanguageInjectionHost getInjectionHost(@NotNull PsiElement element) {
final PsiFile file = element.getContainingFile();
@@ -23,20 +23,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author cdr
*/
public class Place extends SmartList<PsiLanguageInjectionHost.Shred> {
Place(@NotNull List<PsiLanguageInjectionHost.Shred> shreds) {
super(shreds);
}
@NotNull
public SmartPsiElementPointer<PsiLanguageInjectionHost> getHostPointer() {
SmartPsiElementPointer<PsiLanguageInjectionHost> getHostPointer() {
return ((ShredImpl)get(0)).getSmartPointer();
}
public boolean isValid() {
boolean isValid() {
for (PsiLanguageInjectionHost.Shred shred : this) {
if (!shred.isValid()) {
return false;
@@ -45,7 +42,7 @@ public class Place extends SmartList<PsiLanguageInjectionHost.Shred> {
return true;
}
public void dispose() {
void dispose() {
for (PsiLanguageInjectionHost.Shred shred : this) {
shred.dispose();
}
@@ -41,36 +41,46 @@ public class QuickChangeLookAndFeel extends QuickSwitchSchemeAction {
for (UIManager.LookAndFeelInfo lf : lfs) {
group.add(new DumbAwareAction(lf.getName(), "", lf == current ? ourCurrentAction : ourNotCurrentAction) {
public void actionPerformed(AnActionEvent e) {
switchLafAndUpdateUI(lafMan, lf);
switchLafAndUpdateUI(lafMan, lf, false);
}
});
}
}
public static void switchLafAndUpdateUI(@NotNull LafManager lafMan, @NotNull UIManager.LookAndFeelInfo lf) {
public static void switchLafAndUpdateUI(@NotNull final LafManager lafMan, @NotNull UIManager.LookAndFeelInfo lf, boolean async) {
UIManager.LookAndFeelInfo cur = lafMan.getCurrentLookAndFeel();
if (cur == lf) return;
boolean wasDarcula = UIUtil.isUnderDarcula();
final boolean wasDarcula = UIUtil.isUnderDarcula();
lafMan.setCurrentLookAndFeel(lf);
// a twist not to updateUI twice: here and in DarculaInstaller
// double updateUI shall be avoided and causes NPE in some components (HelpView)
Ref<Boolean> updated = Ref.create(false);
LafManagerListener listener = (s) -> updated.set(true);
lafMan.addLafManagerListener(listener);
try {
if (UIUtil.isUnderDarcula()) {
DarculaInstaller.install();
Runnable updater = () -> {
// a twist not to updateUI twice: here and in DarculaInstaller
// double updateUI shall be avoided and causes NPE in some components (HelpView)
Ref<Boolean> updated = Ref.create(false);
LafManagerListener listener = (s) -> updated.set(true);
lafMan.addLafManagerListener(listener);
try {
if (UIUtil.isUnderDarcula()) {
DarculaInstaller.install();
}
else if (wasDarcula) {
DarculaInstaller.uninstall();
}
}
else if (wasDarcula) {
DarculaInstaller.uninstall();
finally {
lafMan.removeLafManagerListener(listener);
if (!updated.get()) {
lafMan.updateUI();
}
}
};
if (async) {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(updater);
}
finally {
lafMan.removeLafManagerListener(listener);
if (!updated.get()) {
lafMan.updateUI();
}
else {
updater.run();
}
}
@@ -244,8 +244,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
UIManager.LookAndFeelInfo lafInfo = (UIManager.LookAndFeelInfo)myComponent.myLafComboBox.getSelectedItem();
update = true;
shouldUpdateUI = false;
//noinspection SSBasedInspection
SwingUtilities.invokeLater(() -> QuickChangeLookAndFeel.switchLafAndUpdateUI(lafManager, lafInfo));
QuickChangeLookAndFeel.switchLafAndUpdateUI(lafManager, lafInfo, true);
}
if (shouldUpdateUI) {
@@ -124,6 +124,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
@Override
public void reloaded(@NotNull SchemeManager<EditorColorsScheme> schemeManager,
@NotNull Collection<? extends EditorColorsScheme> schemes) {
loadBundledSchemes();
initEditableDefaultSchemesCopies();
initEditableBundledSchemesCopies();
}
@@ -777,9 +777,9 @@ public final class EditorUtil {
}
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
TextAttributes foldedTextAttributes = scheme.getAttributes(textAttributesKey);
FontInfo fallbackFont = ComplementaryFontsRegistry.getFontAbleToDisplay((int)c, foldedTextAttributes.getFontType(),
scheme.getFontPreferences(), null);
TextAttributes textAttributes = scheme.getAttributes(textAttributesKey);
int style = textAttributes != null ? textAttributes.getFontType() : Font.PLAIN;
FontInfo fallbackFont = ComplementaryFontsRegistry.getFontAbleToDisplay((int)c, style, scheme.getFontPreferences(), null);
return fallbackFont.canDisplay(codePoint) ? String.valueOf(c) : fallback;
}
}
@@ -34,7 +34,7 @@ public class InsertLineComment extends ActionOnRange {
@Override
public String toString() {
return "LineComment{" + getVirtualFile().getPath() + " " + myInitialStart + " " + getCurrentRange().getStartOffset() + "}";
return "LineComment{" + getVirtualFile().getPath() + " " + myInitialStart + " " + getCurrentRange() + "}";
}
@Override
@@ -1,75 +0,0 @@
From 7a53ed04eeb1c4f6381f535fc090c65368dae9ad Mon Sep 17 00:00:00 2001
From: Kirill Likhodedov <Kirill.Likhodedov@gmail.com>
Date: Fri, 21 Oct 2011 18:07:42 +0400
Subject: [PATCH] Let OptionMap.as() accept ClassLoader as the second
parameter. Modify BeanTool.proxy to expect classLoader or
use Thread#getContextClassLoader (as before) in the case of
null
---
src/main/java/org/ini4j/BasicOptionMap.java | 9 +++++++--
src/main/java/org/ini4j/OptionMap.java | 2 ++
src/main/java/org/ini4j/spi/BeanTool.java | 10 ++++++----
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/ini4j/BasicOptionMap.java b/src/main/java/org/ini4j/BasicOptionMap.java
index d7e665d..3850bf2 100644
--- a/src/main/java/org/ini4j/BasicOptionMap.java
+++ b/src/main/java/org/ini4j/BasicOptionMap.java
@@ -76,12 +76,17 @@ public class BasicOptionMap extends CommonMultiMap<String, String> implements Op
@Override public <T> T as(Class<T> clazz)
{
- return BeanTool.getInstance().proxy(clazz, getDefaultBeanAccess());
+ return BeanTool.getInstance().proxy(clazz, getDefaultBeanAccess(), null);
+ }
+
+ @Override public <T> T as(Class<T> clazz, ClassLoader classLoader)
+ {
+ return BeanTool.getInstance().proxy(clazz, getDefaultBeanAccess(), classLoader);
}
@Override public <T> T as(Class<T> clazz, String keyPrefix)
{
- return BeanTool.getInstance().proxy(clazz, newBeanAccess(keyPrefix));
+ return BeanTool.getInstance().proxy(clazz, newBeanAccess(keyPrefix), null);
}
@Override public String fetch(Object key)
diff --git a/src/main/java/org/ini4j/OptionMap.java b/src/main/java/org/ini4j/OptionMap.java
index dd48089..c13ac73 100644
--- a/src/main/java/org/ini4j/OptionMap.java
+++ b/src/main/java/org/ini4j/OptionMap.java
@@ -25,6 +25,8 @@ public interface OptionMap extends MultiMap<String, String>, CommentedMap<String
<T> T as(Class<T> clazz);
+ <T> T as(Class<T> clazz, ClassLoader classLoader);
+
<T> T as(Class<T> clazz, String keyPrefix);
String fetch(Object key);
diff --git a/src/main/java/org/ini4j/spi/BeanTool.java b/src/main/java/org/ini4j/spi/BeanTool.java
index 05d8be7..7ee22ec 100644
--- a/src/main/java/org/ini4j/spi/BeanTool.java
+++ b/src/main/java/org/ini4j/spi/BeanTool.java
@@ -156,10 +156,12 @@ public class BeanTool
return (T) o;
}
- public <T> T proxy(Class<T> clazz, BeanAccess props)
- {
- return clazz.cast(Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] { clazz },
- new BeanInvocationHandler(props)));
+ public <T> T proxy(Class<T> clazz, BeanAccess props, ClassLoader classLoader) {
+ if (classLoader == null) {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+ return clazz.cast(Proxy.newProxyInstance(classLoader, new Class[]{clazz},
+ new BeanInvocationHandler(props)));
}
@SuppressWarnings("unchecked")
--
1.7.7
@@ -1,39 +0,0 @@
Index: src/main/java/org/ini4j/spi/IniParser.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>x-MacCyrillic
===================================================================
--- src/main/java/org/ini4j/spi/IniParser.java (date 1319206062000)
+++ src/main/java/org/ini4j/spi/IniParser.java (revision )
@@ -114,10 +114,19 @@
{
String sectionName;
- if (line.charAt(line.length() - 1) != SECTION_END)
+ if (line.charAt(line.length() - 1) != SECTION_END)
{
+ int sectionEnd = line.lastIndexOf(SECTION_END);
+ String afterSectionEnd = line.substring(sectionEnd + 1).trim();
+ if (afterSectionEnd.isEmpty() || isComment(afterSectionEnd.charAt(0)))
+ {
+ line = line.substring(0, sectionEnd + 1);
+ }
+ else
+ {
parseError(line, source.getLineNumber());
- }
+ }
+ }
sectionName = unescapeFilter(line.substring(1, line.length() - 1).trim());
if ((sectionName.length() == 0) && !getConfig().isUnnamedSection())
@@ -133,5 +142,9 @@
handler.startSection(sectionName);
return sectionName;
+ }
+
+ private boolean isComment(char c) {
+ return COMMENTS.indexOf(c) >= 0;
}
}
@@ -22,7 +22,6 @@ import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.diff.ItemLatestState;
import com.intellij.openapi.vcs.history.VcsFileRevision;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ExceptionUtil;
import com.intellij.util.Function;
@@ -62,16 +61,7 @@ public class GitHistoryUtilsTest extends GitSingleRepoTest {
@Override
protected void setUp() throws Exception {
super.setUp();
try {
initTest();
}
catch (Exception e) {
super.tearDown();
throw e;
}
}
private void initTest() throws IOException {
myRevisions = new ArrayList<>(7);
myRevisionsAfterRename = new ArrayList<>(4);
@@ -134,24 +124,18 @@ public class GitHistoryUtilsTest extends GitSingleRepoTest {
// newer revisions go first in the log output
for (int i = revisions.length - 1, j = 0; i >= 0; i--, j++) {
String[] details = revisions[j].trim().split("#");
String[] parents;
if (details.length > 2) {
parents = details[2].split(" ");
}
else {
parents = ArrayUtil.EMPTY_STRING_ARRAY;
}
final GitTestRevision revision = new GitTestRevision(details[0], details[1], parents, commitMessages[i],
USER_NAME, USER_EMAIL, USER_NAME, USER_EMAIL, null,
contents[i]);
GitTestRevision revision = new GitTestRevision(details[0], details[1], commitMessages[i],
USER_NAME, USER_EMAIL, USER_NAME, USER_EMAIL, null,
contents[i]);
myRevisions.add(revision);
if (i > RENAME_COMMIT_INDEX) {
myRevisionsAfterRename.add(revision);
}
}
assertEquals(myRevisionsAfterRename.size(), 5);
assertEquals("setUp failed", 5, myRevisionsAfterRename.size());
cd(projectPath);
updateChangeListManager();
}
@Override
@@ -237,17 +221,13 @@ public class GitHistoryUtilsTest extends GitSingleRepoTest {
}
private TestCommit modify(String file) throws IOException {
editAppend(file, "Modified");
FileUtil.appendToFile(new File(file), "Modified");
String message = "Modified PostHighlightingPass";
addCommit(repo, message);
String hash = last(this);
return new TestCommit(hash, message, file);
}
private static void editAppend(String file, String content) throws IOException {
FileUtil.appendToFile(new File(file), content);
}
@NotNull
private String toReadable(@NotNull Collection<VcsFileRevision> history) {
int maxSubjectLength = findMaxLength(history, revision -> revision.getCommitMessage());
@@ -437,11 +417,9 @@ public class GitHistoryUtilsTest extends GitSingleRepoTest {
final String myCommitterEmail;
final String myBranchName;
final byte[] myContent;
private String[] myParents;
public GitTestRevision(String hash,
String gitTimestamp,
String[] parents,
String commitMessage,
String authorName,
String authorEmail,
@@ -451,7 +429,6 @@ public class GitHistoryUtilsTest extends GitSingleRepoTest {
String content) {
myHash = hash;
myDate = gitTimeStampToDate(gitTimestamp);
myParents = parents;
myCommitMessage = commitMessage;
myAuthorName = authorName;
myAuthorEmail = authorEmail;
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks;
@@ -63,4 +49,7 @@ public interface GrClosableBlock extends GrExpression, GrCodeBlock, GrParameters
@NotNull final ResolveState _state,
@Nullable final PsiElement lastParent,
@NotNull final PsiElement place);
@Nullable
PsiType getOwnerType();
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks;
@@ -21,7 +7,7 @@ import com.intellij.psi.*;
import com.intellij.psi.scope.ElementClassHint;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValueProvider.Result;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiTreeUtil;
@@ -43,10 +29,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterLi
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.*;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.params.GrParameterListImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import org.jetbrains.plugins.groovy.lang.resolve.MethodTypeInferencer;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
@@ -98,7 +82,6 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
if (!super.processDeclarations(processor, state, lastParent, place)) return false;
if (!processParameters(processor, state, place)) return false;
if (ResolveUtil.shouldProcessProperties(processor.getHint(ElementClassHint.KEY)) && !ResolveUtil.processElement(processor, getOwner(), state)) return false;
if (!processClosureClassMembers(processor, state, lastParent, place)) return false;
return true;
@@ -295,28 +278,28 @@ public class GrClosableBlockImpl extends GrBlockImpl implements GrClosableBlock
return res;
}
private PsiVariable getOwner() {
return CachedValuesManager.getCachedValue(this, () -> {
final GroovyPsiElement context = PsiTreeUtil.getParentOfType(this, GrTypeDefinition.class, GrClosableBlock.class, GroovyFile.class);
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
PsiType type = null;
if (context instanceof GrTypeDefinition) {
type = factory.createType((PsiClass)context);
}
else if (context instanceof GrClosableBlock) {
type = GrClosureType.create((GrClosableBlock)context, true);
}
else if (context instanceof GroovyFile) {
final PsiClass scriptClass = ((GroovyFile)context).getScriptClass();
if (scriptClass != null && GroovyNamesUtil.isIdentifier(scriptClass.getName())) type = factory.createType(scriptClass);
}
if (type == null) {
type = TypesUtil.getJavaLangObject(this);
}
@Nullable
@Override
public PsiType getOwnerType() {
return CachedValuesManager.getCachedValue(this, () -> Result.create(doGetOwnerType(), PsiModificationTracker.MODIFICATION_COUNT));
}
PsiVariable owner = new GrLightVariable(getManager(), OWNER_NAME, type, this);
return CachedValueProvider.Result.create(owner, PsiModificationTracker.MODIFICATION_COUNT);
});
@Nullable
private PsiType doGetOwnerType() {
final GroovyPsiElement context = PsiTreeUtil.getParentOfType(this, GrTypeDefinition.class, GrClosableBlock.class, GroovyFile.class);
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
if (context instanceof GrTypeDefinition) {
return factory.createType((PsiClass)context);
}
else if (context instanceof GrClosableBlock) {
return ((GrClosableBlock)context).getType();
}
else if (context instanceof GroovyFile) {
final PsiClass scriptClass = ((GroovyFile)context).getScriptClass();
if (scriptClass != null && GroovyNamesUtil.isIdentifier(scriptClass.getName())) return factory.createType(scriptClass);
}
return null;
}
@Override
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.typing
import com.intellij.psi.JavaPsiFacade
@@ -24,16 +10,21 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE
import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.getDelegatesToInfo
class GrClosureDelegateTypeCalculator : GrTypeCalculator<GrReferenceExpression> {
class GrClosureOwnerDelegateTypeCalculator : GrTypeCalculator<GrReferenceExpression> {
override fun getType(expression: GrReferenceExpression): PsiType? {
val method = expression.resolve() as? PsiMethod ?: return null
if ("getDelegate" != method.name || method.parameterList.parametersCount != 0) return null
val methodName = method.name
val delegate = "getDelegate" == methodName
if (!delegate && "getOwner" != methodName) return null
if (method.parameterList.parametersCount != 0) return null
val closureClass = JavaPsiFacade.getInstance(expression.project).findClass(GROOVY_LANG_CLOSURE, expression.resolveScope)
if (closureClass == null || closureClass != method.containingClass) return null
val closure = PsiTreeUtil.getParentOfType(expression, GrClosableBlock::class.java) ?: return null
return getDelegatesToInfo(closure)?.typeToDelegate
return if (delegate) getDelegatesToInfo(closure)?.typeToDelegate else closure.ownerType
}
}
+1 -1
View File
@@ -171,7 +171,7 @@
implementation="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDGMTypeCalculator"/>
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression"
implementationClass="org.jetbrains.plugins.groovy.lang.typing.GrClosureDelegateTypeCalculator"/>
implementationClass="org.jetbrains.plugins.groovy.lang.typing.GrClosureOwnerDelegateTypeCalculator"/>
<typeCalculator forClass="org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall"
implementationClass="org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.path.GrDescriptorReturnTypeCalculator"/>
@@ -37,8 +37,7 @@ class ResolvePropertyTest extends GroovyResolveTestCase {
void testClosureOwner() throws Exception {
PsiReference ref = configureByFile("closureOwner/A.groovy")
PsiElement resolved = ref.resolve()
assertInstanceOf(resolved, PsiVariable)
assertEquals((resolved as PsiVariable).type.canonicalText, "W")
assertInstanceOf(resolved, PsiMethod)
}
void testLocal1() throws Exception {
@@ -818,4 +818,14 @@ def bar() {
void 'test enum values() type'() {
doExprTest 'enum E {}; E.values()', 'E[]'
}
void 'test closure owner type'() {
doTest '''\
class W {
def c = {
<caret>owner
}
}
''', 'W'
}
}