mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -173,15 +173,14 @@ public class JavaStackFrame extends XStackFrame {
|
||||
}
|
||||
|
||||
final Location location = myDescriptor.getLocation();
|
||||
LOG.assertTrue(location != null);
|
||||
|
||||
final ObjectReference thisObjectReference = myDescriptor.getThisObject();
|
||||
if (thisObjectReference != null) {
|
||||
ValueDescriptorImpl thisDescriptor = myNodeManager.getThisDescriptor(null, thisObjectReference);
|
||||
children.add(JavaValue.create(thisDescriptor, evaluationContext, myNodeManager));
|
||||
}
|
||||
else {
|
||||
StaticDescriptorImpl staticDecriptor = myNodeManager.getStaticDescriptor(myDescriptor, location.method().declaringType());
|
||||
else if (location != null) {
|
||||
StaticDescriptorImpl staticDecriptor = myNodeManager.getStaticDescriptor(myDescriptor, location.declaringType());
|
||||
if (staticDecriptor.isExpandable()) {
|
||||
children.addTopGroup(new JavaStaticGroup(staticDecriptor, evaluationContext, myNodeManager));
|
||||
}
|
||||
@@ -214,7 +213,8 @@ public class JavaStackFrame extends XStackFrame {
|
||||
if (classRenderer.SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) {
|
||||
if (thisObjectReference != null && debugProcess.getVirtualMachineProxy().canGetSyntheticAttribute()) {
|
||||
final ReferenceType thisRefType = thisObjectReference.referenceType();
|
||||
if (thisRefType instanceof ClassType && thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only
|
||||
if (thisRefType instanceof ClassType && location != null
|
||||
&& thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only
|
||||
final ClassType clsType = (ClassType)thisRefType;
|
||||
for (Field field : clsType.fields()) {
|
||||
if (DebuggerUtils.isSynthetic(field) && StringUtil.startsWith(field.name(), FieldDescriptorImpl.OUTER_LOCAL_VAR_FIELD_PREFIX)) {
|
||||
|
||||
+1
@@ -281,6 +281,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
|
||||
return myIsInLibraryContent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Location getLocation() {
|
||||
return myLocation;
|
||||
}
|
||||
|
||||
@@ -147,10 +147,7 @@ public class SdkSettingsStep extends ModuleWizardStep {
|
||||
myWizardContext.setProjectJdk(jdk);
|
||||
}
|
||||
else {
|
||||
Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk();
|
||||
if (sdk == null || !myModuleBuilder.isSuitableSdkType(sdk.getSdkType())) {
|
||||
myModuleBuilder.setModuleJdk(myJdkComboBox.getSelectedJdk());
|
||||
} // else, inherit project jdk
|
||||
myModuleBuilder.setModuleJdk(myJdkComboBox.getSelectedJdk());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -575,7 +575,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
}
|
||||
final PsiSubstitutor inferredSubstitutor = TypeConversionUtil.getClassSubstitutor(superClass, classCandidate, classResolveResult.getSubstitutor());
|
||||
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, myAnonymClass.getBaseClassType());
|
||||
if (inferredSubstitutor == null ||
|
||||
if (inferredSubstitutor != null &&
|
||||
!Comparing.equal(inferredSubstitutor.substitute(paramType), substitutor.substitute(paramType))) {
|
||||
myBodyContainsForbiddenRefs = true;
|
||||
return;
|
||||
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
@@ -142,6 +143,7 @@ abstract class JavaModuleFixtureBuilderImpl<T extends ModuleFixture> extends Mod
|
||||
|
||||
final Sdk jdk;
|
||||
if (myJdk != null) {
|
||||
VfsRootAccess.allowRootAccessTemporarily(module, myJdk);
|
||||
jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false);
|
||||
((ProjectJdkImpl)jdk).setVersionString("java 1.5");
|
||||
}
|
||||
|
||||
+3
@@ -37,6 +37,9 @@ public class MockPackageFacadeBuilderService extends BuilderService {
|
||||
catch (ClassNotFoundException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
+23
@@ -328,4 +328,27 @@ public class IncrementalArtifactBuildingTest extends ArtifactBuilderTestCase {
|
||||
assertOutput(a2, fs().file("a.txt", "2"));
|
||||
}
|
||||
|
||||
//todo[nik] fix
|
||||
//ZD-51993
|
||||
public void _testFilesCopiedToTwoDifferentPlacesInArtifact() {
|
||||
final String fileA = createFile("res/a.txt", "0");
|
||||
final String fileB = createFile("res/b.txt", "0");
|
||||
String dir = PathUtil.getParentPath(fileA);
|
||||
JpsArtifact a = addArtifact("a", root()
|
||||
.dir("d").dirCopy(dir).end()
|
||||
.archive("a.zip").dirCopy(dir));
|
||||
buildAll();
|
||||
|
||||
change(fileA, "1");
|
||||
buildAll();
|
||||
assertOutput(a, fs()
|
||||
.dir("d").file("a.txt", "1").file("b.txt", "0").end()
|
||||
.archive("a.zip").file("a.txt", "1").file("b.txt", "0"));
|
||||
|
||||
change(fileB, "1");
|
||||
buildAll();
|
||||
assertOutput(a, fs()
|
||||
.dir("d").file("a.txt", "1").file("b.txt", "1").end()
|
||||
.archive("a.zip").file("a.txt", "1").file("b.txt", "1"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -26,6 +26,8 @@ import com.intellij.util.EventDispatcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
private final EventDispatcher<VirtualFileListener> myEventDispatcher = EventDispatcher.create(VirtualFileListener.class);
|
||||
|
||||
@@ -135,4 +137,39 @@ public abstract class DeprecatedVirtualFileSystem extends VirtualFileSystem {
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
protected void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new UnsupportedOperationException("deleteFile() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException("move() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException("renameFile() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new UnsupportedOperationException("createChildFile() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new UnsupportedOperationException("createChildDirectory() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull VirtualFile newParent,
|
||||
@NotNull String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException("copyFile() not supported");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -84,39 +84,6 @@ public abstract class LightVirtualFileBase extends VirtualFile {
|
||||
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor,
|
||||
@NotNull VirtualFile vFile,
|
||||
@NotNull VirtualFile newParent,
|
||||
@NotNull final String copyName) throws IOException {
|
||||
throw new IOException("Cannot copy files");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new IOException("Cannot create files");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new IOException("Cannot create directories");
|
||||
}
|
||||
}
|
||||
|
||||
private static final MyVirtualFileSystem ourFileSystem = new MyVirtualFileSystem();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -72,40 +71,4 @@ public class CoreJarFileSystem extends DeprecatedVirtualFileSystem {
|
||||
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
|
||||
return findFileByPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile copyFile(Object requestor,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull VirtualFile newParent,
|
||||
@NotNull String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException("JarFileSystem is read-only");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -53,45 +52,4 @@ public class CoreLocalFileSystem extends DeprecatedVirtualFileSystem {
|
||||
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
|
||||
return findFileByPath(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new UnsupportedOperationException("deleteFile() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException("move() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException("renameFile() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new UnsupportedOperationException("createChildFile() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new UnsupportedOperationException("createChildDirectory() not supported");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected VirtualFile copyFile(Object requestor,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull VirtualFile newParent,
|
||||
@NotNull String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException("copyFile() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ public abstract class DiffContentFactory {
|
||||
@NotNull
|
||||
public abstract DocumentContent create(@NotNull String text, @Nullable FileType type);
|
||||
|
||||
@NotNull
|
||||
public abstract DocumentContent create(@NotNull String text, @Nullable FileType type, boolean respectLineSeparators);
|
||||
|
||||
@NotNull
|
||||
public abstract DocumentContent create(@Nullable Project project, @NotNull Document document);
|
||||
|
||||
@@ -65,7 +68,7 @@ public abstract class DiffContentFactory {
|
||||
* @param referenceContent used to detect FileType and proper highlighting for clipboard content
|
||||
*/
|
||||
@NotNull
|
||||
public abstract DocumentContent createClipboardContent(@NotNull DocumentContent referenceContent);
|
||||
public abstract DocumentContent createClipboardContent(@Nullable DocumentContent referenceContent);
|
||||
|
||||
@NotNull
|
||||
public abstract DiffContent createBinary(@Nullable Project project,
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.BinaryLightVirtualFile;
|
||||
import com.intellij.util.LineSeparator;
|
||||
import com.intellij.util.PathUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -37,6 +38,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class DiffContentFactoryImpl extends DiffContentFactory {
|
||||
public final Logger LOG = Logger.getInstance(DiffContentFactoryImpl.class);
|
||||
@@ -56,9 +58,13 @@ public class DiffContentFactoryImpl extends DiffContentFactory {
|
||||
@Override
|
||||
@NotNull
|
||||
public DocumentContent create(@NotNull String text, @Nullable FileType type) {
|
||||
Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(text));
|
||||
document.setReadOnly(true);
|
||||
return new DocumentContentImpl(document, type, null, null, null);
|
||||
return create(text, type, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DocumentContent create(@NotNull String text, @Nullable FileType type, boolean respectLineSeparators) {
|
||||
return createImpl(text, type, null, null, respectLineSeparators, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,17 +108,32 @@ public class DiffContentFactoryImpl extends DiffContentFactory {
|
||||
@Override
|
||||
@NotNull
|
||||
public DiffContent createClipboardContent() {
|
||||
String text = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
|
||||
Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(StringUtil.notNullize(text)));
|
||||
return new DocumentContentImpl(document); // TODO: show difference in line separators ?
|
||||
return createClipboardContent(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DocumentContent createClipboardContent(@NotNull DocumentContent mainContent) {
|
||||
public DocumentContent createClipboardContent(@Nullable DocumentContent mainContent) {
|
||||
String text = CopyPasteManager.getInstance().getContents(DataFlavor.stringFlavor);
|
||||
Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(StringUtil.notNullize(text)));
|
||||
return new DocumentContentWrapper(document, mainContent);
|
||||
|
||||
FileType type = mainContent != null ? mainContent.getContentType() : null;
|
||||
VirtualFile highlightFile = mainContent != null ? mainContent.getHighlightFile() : null;
|
||||
|
||||
return createImpl(StringUtil.notNullize(text), type, highlightFile, null, true, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DocumentContent createImpl(@NotNull String text,
|
||||
@Nullable FileType type,
|
||||
@Nullable VirtualFile highlightFile,
|
||||
@Nullable Charset charset,
|
||||
boolean respectLineSeparators,
|
||||
boolean readOnly) {
|
||||
// TODO: detect invalid (different across the file) separators ?
|
||||
LineSeparator separator = respectLineSeparators ? StringUtil.detectSeparators(text) : null;
|
||||
Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(text));
|
||||
if (readOnly) document.setReadOnly(true);
|
||||
return new DocumentContentImpl(document, type, highlightFile, separator, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@Deprecated
|
||||
/** @deprecated (to be removed in IDEA 15) */
|
||||
public class DocumentContentWrapper implements DocumentContent {
|
||||
@NotNull private final DocumentContent myBase;
|
||||
@NotNull private final Document myDocument;
|
||||
|
||||
@@ -312,11 +312,13 @@ public class SimpleDiffChange {
|
||||
|
||||
boolean isEditable = DiffUtil.isEditable(mySide.select(myEditor1, myEditor2));
|
||||
boolean isOtherEditable = DiffUtil.isEditable(mySide.other().select(myEditor1, myEditor2));
|
||||
boolean isAppendable = myFragment.getStartLine1() != myFragment.getEndLine1() &&
|
||||
myFragment.getStartLine2() != myFragment.getEndLine2();
|
||||
|
||||
if ((myShiftPressed || !isOtherEditable) && isEditable) {
|
||||
return createRevertRenderer(mySide);
|
||||
}
|
||||
if (myCtrlPressed) {
|
||||
if (myCtrlPressed && isAppendable) {
|
||||
return createAppendRenderer(mySide);
|
||||
}
|
||||
return createApplyRenderer(mySide);
|
||||
|
||||
@@ -291,7 +291,6 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
}
|
||||
UIUtil.setHintingForLCDText(g2d);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.intellij.openapi.externalSystem.service.execution;
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 12/12/2014
|
||||
*/
|
||||
public class NotSupportedException extends ExternalSystemException {
|
||||
public NotSupportedException(@Nullable String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotSupportedException(@Nullable Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public NotSupportedException(@Nullable String message, @NotNull String... quickFixes) {
|
||||
super(message, quickFixes);
|
||||
}
|
||||
|
||||
public NotSupportedException(@Nullable String message, @Nullable Throwable cause, @NotNull String... quickFixes) {
|
||||
super(message, cause, quickFixes);
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -6,7 +6,8 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.task.*;
|
||||
import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager;
|
||||
import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade;
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.execution.NotSupportedException;
|
||||
import com.intellij.openapi.externalSystem.service.notification.*;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -190,6 +191,12 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask {
|
||||
setState(result ? ExternalSystemTaskState.CANCELED : ExternalSystemTaskState.CANCELLATION_FAILED);
|
||||
return result;
|
||||
}
|
||||
catch (NotSupportedException e) {
|
||||
NotificationData notification =
|
||||
new NotificationData("Cancellation failed", e.getMessage(), NotificationCategory.WARNING, NotificationSource.PROJECT_SYNC);
|
||||
notification.setBalloonNotification(true);
|
||||
ExternalSystemNotificationManager.getInstance(getIdeProject()).showNotification(getExternalSystemId(), notification);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
setState(ExternalSystemTaskState.CANCELLATION_FAILED);
|
||||
myError.set(e);
|
||||
|
||||
@@ -100,10 +100,14 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
|
||||
public static final Key<ConsoleViewImpl> CONSOLE_VIEW_IN_EDITOR_VIEW = Key.create("CONSOLE_VIEW_IN_EDITOR_VIEW");
|
||||
|
||||
static {
|
||||
private static boolean ourTypedHandlerInitialized;
|
||||
|
||||
private static synchronized void initTypedHandler() {
|
||||
if (ourTypedHandlerInitialized) return;
|
||||
final EditorActionManager actionManager = EditorActionManager.getInstance();
|
||||
final TypedAction typedAction = actionManager.getTypedAction();
|
||||
typedAction.setupHandler(new MyTypedHandler(typedAction.getHandler()));
|
||||
ourTypedHandlerInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,6 +285,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
boolean usePredefinedMessageFilter)
|
||||
{
|
||||
super(new BorderLayout());
|
||||
initTypedHandler();
|
||||
myIsViewer = viewer;
|
||||
myState = initialState;
|
||||
myPsiDisposedCheck = new DisposedPsiManagerCheck(project);
|
||||
|
||||
+3
-1
@@ -157,7 +157,9 @@ public class ClasspathStorage extends StateStorageBase<ClasspathStorage.MyStorag
|
||||
public void analyzeExternalChangesAndUpdateIfNeed(@NotNull Collection<VirtualFile> changedFiles, @NotNull Set<String> componentNames) {
|
||||
// if some file changed, so, changed
|
||||
componentNames.add("NewModuleRootManager");
|
||||
myStorageData.loaded = false;
|
||||
if (myStorageData != null) {
|
||||
myStorageData.loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -42,7 +42,7 @@ public abstract class JarFileSystem extends ArchiveFileSystem implements JarCopy
|
||||
}
|
||||
|
||||
/** @deprecated to be removed in IDEA 15 */
|
||||
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
|
||||
@SuppressWarnings("deprecation")
|
||||
public abstract JarFile getJarFile(@NotNull VirtualFile entryVFile) throws IOException;
|
||||
|
||||
@Nullable
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.intellij.internal.validation;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.impl.ProjectNewWindowDoNotAskOption;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Denis Fokin
|
||||
*/
|
||||
public class CheckMessagesButtonsOrderAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
|
||||
// Case 1
|
||||
|
||||
Messages.showDialog("unchecked unfocused checkbox, [Proceed], ____,Cancel, *Show ussages*",
|
||||
"Message 1", new String [] {"Show usages", "Cancel", "Proceed"}, 0, 0,
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 2
|
||||
|
||||
Messages.showDialog("unchecked unfocused checkbox, [Proceed], ____,Cancel, *Show ussages*",
|
||||
"Message 2", new String [] {"Show usages", "Cancel", "Proceed"}, 0, 1,
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 3
|
||||
|
||||
Messages.showDialog("unchecked unfocused checkbox, [Proceed], ____, *Cancel*, Show ussages",
|
||||
"Message 3", new String [] {"Show usages", "Cancel", "Proceed"}, 1, 0,
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 4
|
||||
|
||||
Messages.showDialog("unchecked unfocused checkbox, [Proceed], ____, *Cancel*, Show ussages",
|
||||
"Message 4", new String [] {"Show usages", "Cancel", "Proceed"}, 1, 1,
|
||||
Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 5
|
||||
|
||||
Messages.showDialog("[Proceed], ____, Cancel, *Show ussages*",
|
||||
"Message 5", new String [] {"Show usages", "Cancel", "Proceed"}, 0, 1,
|
||||
Messages.getQuestionIcon(), null);
|
||||
|
||||
// Case 6
|
||||
|
||||
Messages.showYesNoCancelDialog("unchecked unfocused checkbox, [New Window], ____, Cancel, *This Window*",
|
||||
"Message 6",
|
||||
"This window",
|
||||
"New Window",
|
||||
CommonBundle.getCancelButtonText(),
|
||||
Messages.getQuestionIcon(),
|
||||
new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 7
|
||||
|
||||
Messages.showDialog("[Variant 1], Variant 2, Variant 3, Cancel, *Ok*",
|
||||
"Message 7",
|
||||
new String[]{"Ok", "Cancel", "Variant 3", "Variant 2", "Variant 1"},
|
||||
0, 1, Messages.getQuestionIcon(), null);
|
||||
|
||||
// Case 8
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Variant 1], Variant 2, Variant 3, Cancel, *Ok*",
|
||||
"Message 8",
|
||||
new String [] {"Ok", "Cancel", "Variant 3", "Variant 2", "Variant 1"},
|
||||
0, 0, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 9
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Variant 1], Variant 2, Variant 3, *Cancel*, Ok",
|
||||
"Message 9",
|
||||
new String [] {"Ok", "Cancel", "Variant 3", "Variant 2", "Variant 1"},
|
||||
1, 1, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 10
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Variant 1], Variant 2, Variant 3, Cancel, *Ok*",
|
||||
"Message 10",
|
||||
new String [] {"Ok", "Cancel", "Variant 3", "Variant 2", "Variant 1"},
|
||||
0, 1, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 11
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Variant 1], Variant 2, Variant 3, Cancel, *Ok*",
|
||||
"Message 11",
|
||||
new String [] {"Ok", "Cancel", "Variant 3", "Variant 2", "Variant 1"},
|
||||
0, 1, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 12
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Cancel], Variant 1, Variant 2, Variant 3, *Ok*",
|
||||
"Message 12",
|
||||
new String [] {"Ok", "Variant 3", "Variant 2", "Variant 1", "Cancel"},
|
||||
0, 1, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
// Case 13
|
||||
|
||||
Messages.showDialog( "unchecked unfocused checkbox, [Cancel], Variant 1, Ok, Variant 2, Variant 3, *Ok*",
|
||||
"Message 13",
|
||||
new String [] {"Variant 3", "Variant 2", "Ok", "Variant 1", "Cancel"},
|
||||
0, 1, Messages.getQuestionIcon(), new ProjectNewWindowDoNotAskOption());
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.intellij.notification.impl.actions;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.impl.ProjectNewWindowDoNotAskOption;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Denis Fokin
|
||||
*/
|
||||
public class CheckMessagesButtonsOrderAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
super.run();
|
||||
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String message = "Proceed - focused, [space] ,Cancel - Nothing, Show ussages - default";
|
||||
String[] options = {"Show usages", "Cancel", "Proceed"};
|
||||
Messages.showDialog(message, "First Message", options, 0, 1, Messages.getQuestionIcon(), null);
|
||||
|
||||
|
||||
Messages.showYesNoCancelDialog("unchecked unfocused checkbox, Yes - focused, space, Cancel, No Text - default",
|
||||
IdeBundle.message("title.open.project"),
|
||||
"This window",
|
||||
"New Window",
|
||||
CommonBundle.getCancelButtonText(),
|
||||
Messages.getQuestionIcon(),
|
||||
new ProjectNewWindowDoNotAskOption());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}.start();
|
||||
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -70,8 +70,8 @@ public class ServiceManagerImpl implements BaseComponent {
|
||||
@Override
|
||||
public void extensionAdded(@NotNull final ServiceDescriptor descriptor, final PluginDescriptor pluginDescriptor) {
|
||||
if (descriptor.overrides) {
|
||||
ComponentAdapter oldAdapter =
|
||||
picoContainer.unregisterComponent(descriptor.getInterface());// Allow to re-define service implementations in plugins.
|
||||
// Allow to re-define service implementations in plugins.
|
||||
ComponentAdapter oldAdapter = picoContainer.unregisterComponent(descriptor.getInterface());
|
||||
if (oldAdapter == null) {
|
||||
throw new RuntimeException("Service: " + descriptor.getInterface() + " doesn't override anything");
|
||||
}
|
||||
|
||||
-1
@@ -185,7 +185,6 @@ public abstract class ComponentStoreImpl implements IComponentStore.Reloadable {
|
||||
errors = executeSave(session, readonlyFiles, errors);
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
+51
-31
@@ -18,6 +18,7 @@ package com.intellij.openapi.components.impl.stores;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.highlighter.ProjectFileType;
|
||||
import com.intellij.ide.highlighter.WorkspaceFileType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.*;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.project.impl.ProjectImpl;
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl;
|
||||
import com.intellij.openapi.project.impl.ProjectManagerImpl.UnableToSaveProjectNotification;
|
||||
import com.intellij.openapi.ui.MessageDialogBuilder;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -446,51 +448,69 @@ class ProjectStoreImpl extends BaseFileConfigurableStoreImpl implements IProject
|
||||
|
||||
@Override
|
||||
protected final List<Throwable> doSave(@Nullable List<SaveSession> saveSessions, @NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles, @Nullable List<Throwable> errors) {
|
||||
ProjectImpl.UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(ProjectImpl.UnableToSaveProjectNotification.class, myProject);
|
||||
if (notifications.length > 0) {
|
||||
throw new SaveCancelledException();
|
||||
}
|
||||
|
||||
beforeSave(readonlyFiles);
|
||||
|
||||
super.doSave(saveSessions, readonlyFiles, errors);
|
||||
|
||||
if (!readonlyFiles.isEmpty()) {
|
||||
ReadonlyStatusHandler.OperationStatus status;
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
status = ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(getFilesList(readonlyFiles));
|
||||
UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification.class, myProject);
|
||||
if (readonlyFiles.isEmpty()) {
|
||||
if (notifications.length > 0) {
|
||||
for (UnableToSaveProjectNotification notification : notifications) {
|
||||
notification.expire();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (notifications.length > 0) {
|
||||
throw new SaveCancelledException();
|
||||
}
|
||||
|
||||
ReadonlyStatusHandler.OperationStatus status;
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
status = ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(getFilesList(readonlyFiles));
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
if (status.hasReadonlyFiles()) {
|
||||
dropUnableToSaveProjectNotification(myProject, status.getReadonlyFiles());
|
||||
throw new SaveCancelledException();
|
||||
}
|
||||
else {
|
||||
List<Pair<SaveSession, VirtualFile>> oldList = new ArrayList<Pair<SaveSession, VirtualFile>>(readonlyFiles);
|
||||
readonlyFiles.clear();
|
||||
for (Pair<SaveSession, VirtualFile> entry : oldList) {
|
||||
errors = executeSave(entry.first, readonlyFiles, errors);
|
||||
}
|
||||
|
||||
if (status.hasReadonlyFiles()) {
|
||||
ProjectImpl.dropUnableToSaveProjectNotification(myProject, status.getReadonlyFiles());
|
||||
if (errors != null) {
|
||||
CompoundRuntimeException.doThrow(errors);
|
||||
}
|
||||
|
||||
if (!readonlyFiles.isEmpty()) {
|
||||
dropUnableToSaveProjectNotification(myProject, getFilesList(readonlyFiles));
|
||||
throw new SaveCancelledException();
|
||||
}
|
||||
else {
|
||||
List<Pair<SaveSession, VirtualFile>> oldList = new ArrayList<Pair<SaveSession, VirtualFile>>(readonlyFiles);
|
||||
readonlyFiles.clear();
|
||||
for (Pair<SaveSession, VirtualFile> entry : oldList) {
|
||||
errors = executeSave(entry.first, readonlyFiles, errors);
|
||||
}
|
||||
|
||||
if (errors != null) {
|
||||
CompoundRuntimeException.doThrow(errors);
|
||||
}
|
||||
|
||||
if (!readonlyFiles.isEmpty()) {
|
||||
ProjectImpl.dropUnableToSaveProjectNotification(myProject, getFilesList(readonlyFiles));
|
||||
throw new SaveCancelledException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static void dropUnableToSaveProjectNotification(@NotNull Project project, @NotNull VirtualFile[] readOnlyFiles) {
|
||||
UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification.class, project);
|
||||
if (notifications.length == 0) {
|
||||
Notifications.Bus.notify(new UnableToSaveProjectNotification(project, readOnlyFiles), project);
|
||||
}
|
||||
else {
|
||||
notifications[0].myFiles = readOnlyFiles;
|
||||
}
|
||||
}
|
||||
|
||||
protected void beforeSave(@NotNull List<Pair<SaveSession, VirtualFile>> readonlyFiles) {
|
||||
}
|
||||
|
||||
|
||||
@@ -3088,8 +3088,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (!Comparing.equal(color[i], currentColor)) {
|
||||
currentColor = color[i] != null ? color[i] : JBColor.black;
|
||||
|
||||
UIUtil.updateLCDContrastBasingOnForegroundColor(g, currentColor);
|
||||
|
||||
g.setColor(currentColor);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -19,7 +19,7 @@ import com.intellij.ide.RecentProjectsManager;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.notification.*;
|
||||
import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathMacros;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
@@ -54,9 +54,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.impl.FrameTitleBuilder;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.TimedReference;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.pico.ConstructorInjectionComponentAdapter;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -65,7 +63,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.picocontainer.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -520,59 +517,4 @@ public class ProjectImpl extends PlatformComponentManagerImpl implements Project
|
||||
protected boolean logSlowComponents() {
|
||||
return super.logSlowComponents() || ApplicationInfoImpl.getShadowInstance().isEAP();
|
||||
}
|
||||
|
||||
public static void dropUnableToSaveProjectNotification(@NotNull final Project project, final VirtualFile[] readOnlyFiles) {
|
||||
final UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification.class, project);
|
||||
if (notifications.length == 0) {
|
||||
Notifications.Bus.notify(new UnableToSaveProjectNotification(project, readOnlyFiles), project);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnableToSaveProjectNotification extends Notification {
|
||||
private Project myProject;
|
||||
private final String[] myFileNames;
|
||||
|
||||
private UnableToSaveProjectNotification(@NotNull final Project project, final VirtualFile[] readOnlyFiles) {
|
||||
super("Project Settings", "Could not save project!", buildMessage(), NotificationType.ERROR, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
final UnableToSaveProjectNotification unableToSaveProjectNotification = (UnableToSaveProjectNotification)notification;
|
||||
final Project _project = unableToSaveProjectNotification.getProject();
|
||||
notification.expire();
|
||||
|
||||
if (_project != null && !_project.isDisposed()) {
|
||||
_project.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myProject = project;
|
||||
myFileNames = ContainerUtil.map(readOnlyFiles, new Function<VirtualFile, String>() {
|
||||
@Override
|
||||
public String fun(VirtualFile file) {
|
||||
return file.getPresentableUrl();
|
||||
}
|
||||
}, new String[readOnlyFiles.length]);
|
||||
}
|
||||
|
||||
public String[] getFileNames() {
|
||||
return myFileNames;
|
||||
}
|
||||
|
||||
private static String buildMessage() {
|
||||
return "<p>Unable to save project files. Please ensure project files are writable and you have permissions to modify them." +
|
||||
" <a href=\"\">Try to save project again</a>.</p>";
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expire() {
|
||||
myProject = null;
|
||||
super.expire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+56
-10
@@ -23,6 +23,9 @@ import com.intellij.ide.RecentProjectsManager;
|
||||
import com.intellij.ide.impl.ProjectUtil;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.*;
|
||||
@@ -42,7 +45,6 @@ import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileEvent;
|
||||
@@ -67,6 +69,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
@@ -976,17 +979,30 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean ensureCouldCloseIfUnableToSave(@NotNull final Project project) {
|
||||
final ProjectImpl.UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(ProjectImpl.UnableToSaveProjectNotification.class, project);
|
||||
if (notifications.length == 0) return true;
|
||||
private static boolean ensureCouldCloseIfUnableToSave(@NotNull Project project) {
|
||||
UnableToSaveProjectNotification[] notifications =
|
||||
NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification.class, project);
|
||||
if (notifications.length == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final String fileNames = StringUtil.join(notifications[0].getFileNames(), "\n");
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append(String.format("%s was unable to save some project files,\nare you sure you want to close this project anyway?",
|
||||
ApplicationNamesInfo.getInstance().getProductName()));
|
||||
|
||||
final String msg = String.format("%s was unable to save some project files,\nare you sure you want to close this project anyway?",
|
||||
ApplicationNamesInfo.getInstance().getProductName());
|
||||
return Messages.showDialog(project, msg, "Unsaved Project", "Read-only files:\n\n" + fileNames, new String[]{"Yes", "No"}, 0, 1,
|
||||
Messages.getWarningIcon()) == 0;
|
||||
message.append("\n\nRead-only files:\n");
|
||||
int count = 0;
|
||||
VirtualFile[] files = notifications[0].myFiles;
|
||||
for (VirtualFile file : files) {
|
||||
if (count == 10) {
|
||||
message.append('\n').append("and ").append(files.length - count).append(" more").append('\n');
|
||||
}
|
||||
else {
|
||||
message.append(file.getPath()).append('\n');
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return Messages.showYesNoDialog(project, message.toString(), "Unsaved Project", Messages.getWarningIcon()) == Messages.YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -1039,4 +1055,34 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt
|
||||
public String getPresentableName() {
|
||||
return ProjectBundle.message("project.default.settings");
|
||||
}
|
||||
|
||||
public static class UnableToSaveProjectNotification extends Notification {
|
||||
private Project myProject;
|
||||
public VirtualFile[] myFiles;
|
||||
|
||||
public UnableToSaveProjectNotification(@NotNull final Project project, final VirtualFile[] readOnlyFiles) {
|
||||
super("Project Settings", "Could not save project", "Unable to save project files. Please ensure project files are writable and you have permissions to modify them." +
|
||||
" <a href=\"\">Try to save project again</a>.", NotificationType.ERROR, new NotificationListener() {
|
||||
@Override
|
||||
public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) {
|
||||
final UnableToSaveProjectNotification unableToSaveProjectNotification = (UnableToSaveProjectNotification)notification;
|
||||
final Project _project = unableToSaveProjectNotification.myProject;
|
||||
notification.expire();
|
||||
|
||||
if (_project != null && !_project.isDisposed()) {
|
||||
_project.save();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myProject = project;
|
||||
myFiles = readOnlyFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expire() {
|
||||
myProject = null;
|
||||
super.expire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -98,17 +98,6 @@ public class DummyFileSystem extends DeprecatedVirtualFileSystem implements NonP
|
||||
fireFileDeleted(requestor, vFile, vFile.getName(), parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent, @NotNull final String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
final String oldName = vFile.getName();
|
||||
|
||||
+1
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -84,27 +84,6 @@ public abstract class HttpFileSystemBase extends HttpFileSystem {
|
||||
return createChild(vDir, fileName, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent, @NotNull final String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String extractPresentableUrl(@NotNull String path) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.newvfs.impl;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
@@ -24,6 +25,7 @@ import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.roots.OrderEnumerator;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -170,6 +172,18 @@ public class VfsRootAccess {
|
||||
ourAdditionalRoots.add(FileUtil.toSystemIndependentName(root));
|
||||
}
|
||||
}
|
||||
@TestOnly
|
||||
public static void allowRootAccessTemporarily(@NotNull Disposable disposable, @NotNull final String... roots) {
|
||||
for (String root : roots) {
|
||||
ourAdditionalRoots.add(FileUtil.toSystemIndependentName(root));
|
||||
}
|
||||
Disposer.register(disposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
disallowRootAccess(roots);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static void disallowRootAccess(@NotNull String... roots) {
|
||||
|
||||
@@ -111,6 +111,9 @@ public class SheetController {
|
||||
|
||||
myResult = null;
|
||||
|
||||
int defaultButtonIndex = -1;
|
||||
int focusedButtonIndex = -1;
|
||||
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
String buttonTitle = buttonTitles[i];
|
||||
|
||||
@@ -119,13 +122,18 @@ public class SheetController {
|
||||
handleMnemonics(i, buttonTitle);
|
||||
|
||||
if (buttonTitle.equals(defaultButtonTitle)) {
|
||||
myDefaultButton = buttons[i];
|
||||
defaultButtonIndex = i;
|
||||
}
|
||||
if (buttonTitle.equals(focusedButton)) {
|
||||
myFocusedButton = buttons[i];
|
||||
focusedButtonIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
myFocusedButton = (focusedButtonIndex == -1) ? buttons[buttons.length - 1] : buttons[focusedButtonIndex];
|
||||
myDefaultButton = (defaultButtonIndex == -1 && focusedButtonIndex != defaultButtonIndex) ? buttons[0] : buttons[defaultButtonIndex];
|
||||
|
||||
myDefaultButton = buttons[0];
|
||||
|
||||
if (myFocusedButton == null) {
|
||||
myFocusedButton = myDefaultButton;
|
||||
}
|
||||
|
||||
@@ -161,7 +161,6 @@
|
||||
<action id="NextTab">
|
||||
<keyboard-shortcut first-keystroke="alt RIGHT"/>
|
||||
<keyboard-shortcut first-keystroke="control X" second-keystroke="N"/>
|
||||
<keyboard-shortcut first-keystroke="control X" second-keystroke="O"/>
|
||||
</action>
|
||||
<action id="NextEditorTab">
|
||||
<keyboard-shortcut first-keystroke="alt shift RIGHT"/>
|
||||
@@ -262,7 +261,7 @@
|
||||
<keyboard-shortcut first-keystroke="control 5"/>
|
||||
</action>
|
||||
<action id="NextSplitter">
|
||||
<keyboard-shortcut first-keystroke="control X" second-keystrole="O"/>
|
||||
<keyboard-shortcut first-keystroke="control X" second-keystroke="O"/>
|
||||
</action>
|
||||
<action id="Replace">
|
||||
<keyboard-shortcut first-keystroke="shift alt 5"/>
|
||||
|
||||
@@ -635,7 +635,7 @@
|
||||
<action id="TestMessageBoxAction" internal="true" class="com.intellij.diagnostic.TestMessageBoxAction" text="Show Test Dialog"/>
|
||||
<separator/>
|
||||
<group id="Internal.focusAndModality" popup="true" text="Focus and modality testing">
|
||||
<action id="CheckMessagesButtonsOrderAction" internal="true" class="com.intellij.notification.impl.actions.CheckMessagesButtonsOrderAction"
|
||||
<action id="CheckMessagesButtonsOrderAction" internal="true" class="com.intellij.internal.validation.CheckMessagesButtonsOrderAction"
|
||||
text="Check Messages Buttons Order"/>
|
||||
<action id="ShowDelayedMessageInternalAction" internal="true" class="com.intellij.notification.impl.actions.ShowDelayedMessageInternalAction"
|
||||
text="Show Delayed Message"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -61,39 +60,6 @@ public class MockVirtualFileSystem extends DeprecatedVirtualFileSystem {
|
||||
public void refresh(boolean asynchronous) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent, @NotNull final String copyName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualFile refreshAndFindFileByPath(@NotNull String path) {
|
||||
return findFileByPath(path);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -24,7 +24,6 @@ import static com.intellij.util.BitUtil.isSet;
|
||||
* @version 11.1
|
||||
* @see FileSystemUtil#getAttributes(String)
|
||||
*/
|
||||
@SuppressWarnings("OctalInteger")
|
||||
public final class FileAttributes {
|
||||
public enum Type { FILE, DIRECTORY, SPECIAL }
|
||||
|
||||
|
||||
@@ -71,8 +71,6 @@ public class GraphicsUtil {
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
enableAA ? RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
|
||||
UIUtil.setHintingForLCDText(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1771,56 +1771,6 @@ public class UIUtil {
|
||||
Map map = (Map)tk.getDesktopProperty("awt.font.desktophints");
|
||||
if (map != null) {
|
||||
g2d.addRenderingHints(map);
|
||||
setHintingForLCDText(g2d);
|
||||
}
|
||||
}
|
||||
|
||||
private static int THEME_BASED_TEXT_LCD_CONTRAST = 0;
|
||||
private static int BEST_DARK_LCD_CONTRAST = 250;
|
||||
private static int BEST_LIGHT_LCD_CONTRAST = 100;
|
||||
|
||||
public static int getContrastForColor (Color color) {
|
||||
// YIQ
|
||||
int yiqValue = ((color.getRed() * 299) + (color.getGreen() * 587) + (color.getBlue() * 114)) / 1000;
|
||||
return yiqValue * 150/255 + 100;
|
||||
}
|
||||
|
||||
|
||||
public static void updateLCDContrastBasingOnForegroundColor(Graphics g, Color color) {
|
||||
Graphics2D g2d = (Graphics2D)g;
|
||||
|
||||
if (SystemInfo.isJetbrainsJvm && Registry.is("force.subpixel.hinting")) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, getContrastForColor(color));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setHintingForLCDText(Graphics2D g2d) {
|
||||
if (SystemInfo.isJetbrainsJvm && Registry.is("force.subpixel.hinting")) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
|
||||
|
||||
// According to JavaDoc we can set values form 100 to 250
|
||||
// So we can use 0 as a special flag
|
||||
int registryLcdContrastValue = Registry.intValue("lcd.contrast.value");
|
||||
if (registryLcdContrastValue == THEME_BASED_TEXT_LCD_CONTRAST) {
|
||||
if (isUnderDarcula()) {
|
||||
registryLcdContrastValue = BEST_DARK_LCD_CONTRAST;
|
||||
} else {
|
||||
registryLcdContrastValue = BEST_LIGHT_LCD_CONTRAST;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrong values prevent IDE from start
|
||||
// So we have to be careful
|
||||
if (registryLcdContrastValue < 100) {
|
||||
LOG.warn("Wrong value of text LCD contrast " + registryLcdContrastValue);
|
||||
registryLcdContrastValue = 100;
|
||||
} else if (registryLcdContrastValue > 250) {
|
||||
LOG.warn("Wrong value of text LCD contrast " + registryLcdContrastValue);
|
||||
registryLcdContrastValue = 250;
|
||||
}
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST, registryLcdContrastValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -21,11 +21,8 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class VcsFileSystem extends DeprecatedVirtualFileSystem {
|
||||
|
||||
public static final String COULD_NOT_IMPLEMENT_MESSAGE = VcsBundle.message("exception.text.internal.errror.could.not.implement.method");
|
||||
private static final String PROTOCOL = "vcs";
|
||||
|
||||
@@ -72,37 +69,4 @@ public class VcsFileSystem extends DeprecatedVirtualFileSystem {
|
||||
protected void fireBeforeContentsChange(Object requestor, @NotNull VirtualFile file) {
|
||||
super.fireBeforeContentsChange(requestor, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFile(Object requestor, @NotNull VirtualFile vFile) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile copyFile(Object requestor, @NotNull VirtualFile vFile, @NotNull VirtualFile newParent, @NotNull final String copyName) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameFile(Object requestor, @NotNull VirtualFile vFile, @NotNull String newName) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
|
||||
throw new RuntimeException(COULD_NOT_IMPLEMENT_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1283,6 +1283,10 @@
|
||||
key="bigdecimal.legacy.method.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.language.level.specific.issues.and.migration.aids" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.migration.BigDecimalLegacyMethodInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="EqualsReplaceableByObjectsCall" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="equals.replaceable.by.objects.call.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.language.level.specific.issues.and.migration.aids" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.migration.EqualsReplaceableByObjectsCallInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="EnumerationCanBeIteration" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="enumeration.can.be.iteration.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.language.level.specific.issues.and.migration.aids" enabledByDefault="false" level="WARNING"
|
||||
|
||||
+4
-1
@@ -2151,4 +2151,7 @@ use.of.clone.reference.problem.descriptor=Use of <code>#ref</code>
|
||||
dangling.javadoc.display.name=Dangling Javadoc comment
|
||||
dangling.javadoc.problem.descriptor=Dangling Javadoc comment #loc
|
||||
dangling.javadoc.convert.quickfix=Replace with block comment
|
||||
dangling.javadoc.delete.quickfix=Remove dangling comment
|
||||
dangling.javadoc.delete.quickfix=Remove dangling comment
|
||||
equals.replaceable.by.objects.call.display.name='equals()' expression replaceable by 'Objects.equals()' expression
|
||||
equals.replaceable.by.objects.call.problem.descriptor=<code>#ref</code> replaceable by 'Objects.equals()' expression #loc
|
||||
equals.replaceable.by.objects.call.quickfix=Replace with 'Objects.equals()' expression
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.siyeh.ig.migration;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.HardcodedMethodConstants;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class EqualsReplaceableByObjectsCallInspection extends BaseInspection {
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message("equals.replaceable.by.objects.call.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message("equals.replaceable.by.objects.call.problem.descriptor");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
return new EqualsReplaceableByObjectsCallFix((String)infos[0], (String)infos[1], (Boolean)infos[2]);
|
||||
}
|
||||
|
||||
private static class EqualsReplaceableByObjectsCallFix extends InspectionGadgetsFix {
|
||||
|
||||
private final String myName1;
|
||||
private final String myName2;
|
||||
private final Boolean myEquals;
|
||||
|
||||
public EqualsReplaceableByObjectsCallFix(String name1, String name2, Boolean equals) {
|
||||
myName1 = name1;
|
||||
myName2 = name2;
|
||||
myEquals = equals;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return InspectionGadgetsBundle.message("equals.replaceable.by.objects.call.quickfix");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (!(element instanceof PsiBinaryExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiBinaryExpression expression = (PsiBinaryExpression)element;
|
||||
if (myEquals) {
|
||||
PsiReplacementUtil.replaceExpressionAndShorten(expression, "java.util.Objects.equals(" + myName1 + "," + myName2 + ")");
|
||||
}
|
||||
else {
|
||||
PsiReplacementUtil.replaceExpressionAndShorten(expression, "!java.util.Objects.equals(" + myName1 + "," + myName2 + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldInspect(PsiFile file) {
|
||||
return PsiUtil.isLanguageLevel7OrHigher(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new EqualsReplaceableByObjectsCallVisitor();
|
||||
}
|
||||
|
||||
private static class EqualsReplaceableByObjectsCallVisitor extends BaseInspectionVisitor {
|
||||
|
||||
@Override
|
||||
public void visitBinaryExpression(PsiBinaryExpression expression) {
|
||||
final IElementType tokenType = expression.getOperationTokenType();
|
||||
if (JavaTokenType.ANDAND.equals(tokenType)) {
|
||||
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), false);
|
||||
if (variable == null) {
|
||||
return;
|
||||
}
|
||||
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(expression.getROperand(), variable);
|
||||
if (otherVariable == null) {
|
||||
return;
|
||||
}
|
||||
checkEqualityBefore(expression, true, variable, otherVariable);
|
||||
}
|
||||
else if (JavaTokenType.OROR.equals(tokenType)) {
|
||||
final PsiVariable variable = ExpressionUtils.getVariableFromNullComparison(expression.getLOperand(), true);
|
||||
if (variable == null) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression rhs = ParenthesesUtils.stripParentheses(expression.getROperand());
|
||||
if (!(rhs instanceof PsiPrefixExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)rhs;
|
||||
if (!JavaTokenType.EXCL.equals(prefixExpression.getOperationTokenType())) {
|
||||
return;
|
||||
}
|
||||
final PsiVariable otherVariable = getArgumentFromEqualsCallOn(prefixExpression.getOperand(), variable);
|
||||
if (otherVariable == null) {
|
||||
return;
|
||||
}
|
||||
checkEqualityBefore(expression, false, variable, otherVariable);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEqualityBefore(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
|
||||
final PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
|
||||
if (parent instanceof PsiBinaryExpression) {
|
||||
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)parent;
|
||||
if (PsiTreeUtil.isAncestor(binaryExpression.getROperand(), expression, false)) {
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
if (isEquality(lhs, equals, variable1, variable2)) {
|
||||
registerError(binaryExpression, variable1.getName(), variable2.getName(), Boolean.valueOf(equals));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
registerError(expression, variable1.getName(), variable2.getName(), Boolean.valueOf(equals));
|
||||
}
|
||||
|
||||
private static boolean isEquality(PsiExpression expression, boolean equals, PsiVariable variable1, PsiVariable variable2) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiBinaryExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
|
||||
if (equals) {
|
||||
if (!JavaTokenType.EQEQ.equals(binaryExpression.getOperationTokenType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!JavaTokenType.NE.equals(binaryExpression.getOperationTokenType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
final PsiExpression rhs = binaryExpression.getROperand();
|
||||
return (VariableAccessUtils.evaluatesToVariable(lhs, variable1) && VariableAccessUtils.evaluatesToVariable(rhs, variable2)) ||
|
||||
(VariableAccessUtils.evaluatesToVariable(lhs, variable2) && VariableAccessUtils.evaluatesToVariable(rhs, variable1));
|
||||
}
|
||||
|
||||
private static PsiVariable getArgumentFromEqualsCallOn(PsiExpression expression, @NotNull PsiVariable variable) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiMethodCallExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!HardcodedMethodConstants.EQUALS.equals(methodName)) {
|
||||
return null;
|
||||
}
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (!VariableAccessUtils.evaluatesToVariable(qualifier, variable)) {
|
||||
return null;
|
||||
}
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if (expressions.length != 1) {
|
||||
return null;
|
||||
}
|
||||
return ExpressionUtils.getVariable(expressions[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -593,4 +593,48 @@ public class ExpressionUtils {
|
||||
final IElementType tokenType = prefixExpression.getOperationTokenType();
|
||||
return JavaTokenType.MINUS.equals(tokenType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiVariable getVariableFromNullComparison(PsiExpression expression, boolean equals) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiPolyadicExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
|
||||
final IElementType tokenType = polyadicExpression.getOperationTokenType();
|
||||
if (equals) {
|
||||
if (!JavaTokenType.EQEQ.equals(tokenType)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!JavaTokenType.NE.equals(tokenType)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final PsiExpression[] operands = polyadicExpression.getOperands();
|
||||
if (operands.length != 2) {
|
||||
return null;
|
||||
}
|
||||
if (PsiType.NULL.equals(operands[0].getType())) {
|
||||
return getVariable(operands[1]);
|
||||
}
|
||||
else if (PsiType.NULL.equals(operands[1].getType())) {
|
||||
return getVariable(operands[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PsiVariable getVariable(PsiExpression expression) {
|
||||
expression = ParenthesesUtils.stripParentheses(expression);
|
||||
if (!(expression instanceof PsiReferenceExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
|
||||
final PsiElement target = referenceExpression.resolve();
|
||||
if (!(target instanceof PsiVariable)) {
|
||||
return null;
|
||||
}
|
||||
return (PsiVariable)target;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports expressions that can be replaced with a call to <code>java.util.Objects.equals()</code>, which is available since JDK 1.7.
|
||||
For example:
|
||||
<code><pre>a != <b>null</b> <b>&&</b> a.equals(b)</pre></code>
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
This inspection only reports if the project or module is configured to use a language level of 7 or higher.
|
||||
<p>
|
||||
<small>New in 15</small>
|
||||
</body>
|
||||
</html>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class EqualsReplaceableByObjectsCall {
|
||||
void yyy(Object a, Object b) {
|
||||
boolean c = <warning descr="'(a != null) && a.equals(b)' replaceable by 'Objects.equals()' expression">(a != null) && a.equals(b)</warning>;
|
||||
boolean d = <warning descr="'(a != b) && (a == null || !a.equals(b))' replaceable by 'Objects.equals()' expression">(a != b) && (a == null || !a.equals(b))</warning>;
|
||||
boolean e = <warning descr="'((a) == (b)) || ((a) != (null) && (a).equals((b)))' replaceable by 'Objects.equals()' expression">((a) == (b)) || ((a) != (null) && (a).equals((b)))</warning>;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.siyeh.ig.migration;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class EqualsReplaceableByObjectsCallInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testEqualsReplaceableByObjectsCall() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new EqualsReplaceableByObjectsCallInspection();
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class PsiDiffContentFactory {
|
||||
if (containingFile == null) {
|
||||
String text = psiElement.getText();
|
||||
if (text == null) return null;
|
||||
return DiffContentFactory.getInstance().create(text, psiElement.getLanguage().getAssociatedFileType());
|
||||
return DiffContentFactory.getInstance().create(text, psiElement.getLanguage().getAssociatedFileType(), false);
|
||||
}
|
||||
DocumentContent wholeFileContent = DiffContentFactory.getInstance().createDocument(psiElement.getProject(), containingFile.getVirtualFile());
|
||||
if (wholeFileContent == null) return null;
|
||||
|
||||
@@ -17,27 +17,20 @@ package org.jetbrains.plugins.gradle;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.SimpleJavaParameters;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemAutoImportAware;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemConfigurableAware;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemManager;
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemUiAware;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalSystemProjectResolver;
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.CachingExternalSystemAutoImportAware;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.ui.DefaultExternalSystemUiAware;
|
||||
import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
|
||||
import com.intellij.openapi.externalSystem.util.DisposeAwareProjectChange;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
@@ -45,7 +38,6 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.util.AtomicNotNullLazyValue;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
@@ -291,38 +283,6 @@ public class GradleManager
|
||||
ensureProjectsRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProjectsLinked(@NotNull Collection<GradleProjectSettings> settings) {
|
||||
final ProjectDataManager projectDataManager = ServiceManager.getService(ProjectDataManager.class);
|
||||
for (GradleProjectSettings gradleProjectSettings : settings) {
|
||||
ExternalSystemUtil.refreshProject(
|
||||
project, GradleConstants.SYSTEM_ID, gradleProjectSettings.getExternalProjectPath(),
|
||||
new ExternalProjectRefreshCallback() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable final DataNode<ProjectData> externalProject) {
|
||||
if (externalProject == null) {
|
||||
return;
|
||||
}
|
||||
ExternalSystemApiUtil.executeProjectChangeAction(true, new DisposeAwareProjectChange(project) {
|
||||
@Override
|
||||
public void execute() {
|
||||
ProjectRootManagerEx.getInstanceEx(project).mergeRootsChangesDuring(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
projectDataManager.importData(externalProject.getKey(), Collections.singleton(externalProject), project, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull String errorMessage, @Nullable String errorDetails) {
|
||||
}
|
||||
}, false, ProgressExecutionMode.MODAL_SYNC);
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureProjectsRefresh() {
|
||||
ExternalSystemUtil.refreshProjects(project, GradleConstants.SYSTEM_ID, true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public class GradleBuildProcessParametersProvider extends BuildProcessParameters
|
||||
File[] children = FileUtil.notNullize(gradleLibDir.listFiles());
|
||||
for (File child : children) {
|
||||
final String fileName = child.getName();
|
||||
if (fileName.endsWith(".jar") && !fileName.startsWith("logback-") && child.isFile()) {
|
||||
if (fileName.endsWith(".jar") && child.isFile()) {
|
||||
classpath.add(child.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.gradle.service.execution;
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.execution.NotSupportedException;
|
||||
import org.gradle.tooling.CancellationToken;
|
||||
import org.gradle.tooling.CancellationTokenSource;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 3/25/2015
|
||||
*/
|
||||
public class UnsupportedCancellationToken implements CancellationTokenSource {
|
||||
@Override
|
||||
public void cancel() {
|
||||
throw new NotSupportedException("Configured version of Gradle does not support cancellation. \nPlease, use Gradle 2.1 or newer.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CancellationToken token() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -370,8 +370,11 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Class> getExtraProjectModelClasses() {
|
||||
return ContainerUtil.<Class>set(
|
||||
GradleBuild.class, ExternalProject.class, ModuleExtendedModel.class, BuildScriptClasspathModel.class);
|
||||
Set<Class> result = ContainerUtil.<Class>set(GradleBuild.class, ExternalProject.class, ModuleExtendedModel.class);
|
||||
if (!resolverCtx.isPreviewMode()) {
|
||||
result.add(BuildScriptClasspathModel.class);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+13
-1
@@ -35,6 +35,7 @@ import org.gradle.tooling.internal.consumer.DefaultExecutorServiceFactory;
|
||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
||||
import org.gradle.tooling.internal.consumer.Distribution;
|
||||
import org.gradle.tooling.model.build.BuildEnvironment;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.settings.DistributionType;
|
||||
@@ -443,7 +444,18 @@ public class GradleExecutionHelper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static BuildEnvironment getBuildEnvironment(@NotNull ProjectConnection connection) {
|
||||
public static GradleVersion getGradleVersion(@NotNull ProjectConnection connection) {
|
||||
final BuildEnvironment buildEnvironment = getBuildEnvironment(connection);
|
||||
|
||||
GradleVersion gradleVersion = null;
|
||||
if (buildEnvironment != null) {
|
||||
gradleVersion = GradleVersion.version(buildEnvironment.getGradle().getGradleVersion());
|
||||
}
|
||||
return gradleVersion;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BuildEnvironment getBuildEnvironment(@NotNull ProjectConnection connection) {
|
||||
try {
|
||||
return connection.getModel(BuildEnvironment.class);
|
||||
}
|
||||
|
||||
+10
-11
@@ -44,10 +44,12 @@ import org.gradle.tooling.model.build.BuildEnvironment;
|
||||
import org.gradle.tooling.model.idea.BasicIdeaProject;
|
||||
import org.gradle.tooling.model.idea.IdeaModule;
|
||||
import org.gradle.tooling.model.idea.IdeaProject;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
|
||||
import org.jetbrains.plugins.gradle.remote.impl.GradleLibraryNamesMixer;
|
||||
import org.jetbrains.plugins.gradle.service.execution.UnsupportedCancellationToken;
|
||||
import org.jetbrains.plugins.gradle.settings.ClassHolder;
|
||||
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
@@ -150,6 +152,11 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
parametersList.addProperty(jvmArg.getKey(), jvmArg.getValue());
|
||||
}
|
||||
|
||||
final BuildEnvironment buildEnvironment = GradleExecutionHelper.getBuildEnvironment(resolverCtx.getConnection());
|
||||
GradleVersion gradleVersion = null;
|
||||
if (buildEnvironment != null) {
|
||||
gradleVersion = GradleVersion.version(buildEnvironment.getGradle().getGradleVersion());
|
||||
}
|
||||
|
||||
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = resolverCtx.getConnection().action(projectImportAction);
|
||||
|
||||
@@ -169,6 +176,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
buildActionExecutor.withCancellationToken(cancellationTokenSource.token());
|
||||
synchronized (myCancellationMap) {
|
||||
myCancellationMap.putValue(resolverCtx.getExternalSystemTaskId(), cancellationTokenSource);
|
||||
if (gradleVersion != null && gradleVersion.compareTo(GradleVersion.version("2.1")) < 0) {
|
||||
myCancellationMap.putValue(resolverCtx.getExternalSystemTaskId(), new UnsupportedCancellationToken());
|
||||
}
|
||||
}
|
||||
allModels = buildActionExecutor.run();
|
||||
if (allModels == null) {
|
||||
@@ -196,7 +206,6 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
}
|
||||
}
|
||||
|
||||
final BuildEnvironment buildEnvironment = getBuildEnvironment(resolverCtx);
|
||||
allModels.setBuildEnvironment(buildEnvironment);
|
||||
resolverCtx.setModels(allModels);
|
||||
|
||||
@@ -280,16 +289,6 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver<Grad
|
||||
return projectDataNode;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static BuildEnvironment getBuildEnvironment(@NotNull ProjectResolverContext resolverCtx) {
|
||||
try {
|
||||
return resolverCtx.getConnection().getModel(BuildEnvironment.class);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleBuildSrcProject(@NotNull final DataNode<ProjectData> resultProjectDataNode,
|
||||
@NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
|
||||
|
||||
|
||||
+11
-3
@@ -32,11 +32,13 @@ import org.gradle.tooling.BuildLauncher;
|
||||
import org.gradle.tooling.CancellationTokenSource;
|
||||
import org.gradle.tooling.GradleConnector;
|
||||
import org.gradle.tooling.ProjectConnection;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper;
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver;
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverExtension;
|
||||
import org.jetbrains.plugins.gradle.service.execution.UnsupportedCancellationToken;
|
||||
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
@@ -118,11 +120,17 @@ public class GradleTaskManager extends AbstractExternalSystemTaskManager<GradleE
|
||||
}
|
||||
}
|
||||
|
||||
GradleVersion gradleVersion = GradleExecutionHelper.getGradleVersion(connection);
|
||||
BuildLauncher launcher = myHelper.getBuildLauncher(id, connection, settings, listener, vmOptions, scriptParameters);
|
||||
launcher.forTasks(ArrayUtil.toStringArray(taskNames));
|
||||
final CancellationTokenSource cancellationTokenSource = GradleConnector.newCancellationTokenSource();
|
||||
launcher.withCancellationToken(cancellationTokenSource.token());
|
||||
myCancellationMap.put(id, cancellationTokenSource);
|
||||
|
||||
if (gradleVersion != null && gradleVersion.compareTo(GradleVersion.version("2.1")) < 0) {
|
||||
myCancellationMap.put(id, new UnsupportedCancellationToken());
|
||||
} else {
|
||||
final CancellationTokenSource cancellationTokenSource = GradleConnector.newCancellationTokenSource();
|
||||
launcher.withCancellationToken(cancellationTokenSource.token());
|
||||
myCancellationMap.put(id, cancellationTokenSource);
|
||||
}
|
||||
try {
|
||||
launcher.run();
|
||||
}
|
||||
|
||||
@@ -1,23 +1,6 @@
|
||||
package org.jetbrains.plugins.gradle.util;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.classic.spi.ThrowableProxy;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask;
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState;
|
||||
import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager;
|
||||
import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager;
|
||||
import com.intellij.openapi.externalSystem.service.notification.NotificationCategory;
|
||||
import com.intellij.openapi.externalSystem.service.notification.NotificationData;
|
||||
import com.intellij.openapi.externalSystem.service.notification.NotificationSource;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.gradle.tooling.internal.consumer.connection.NonCancellableConsumerConnectionAdapter;
|
||||
import org.jetbrains.plugins.gradle.service.notification.OpenGradleSettingsCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -27,65 +10,6 @@ public class GradleLog {
|
||||
|
||||
public static final Logger LOG = Logger.getInstance(GradleLog.class);
|
||||
|
||||
private static final String GRADLE_PROVIDER_DOES_NOT_SUPPORT_CANCELLATION_MESSAGE =
|
||||
"Note: Version of Gradle provider does not support cancellation. Upgrade your Gradle build.";
|
||||
|
||||
private GradleLog() {
|
||||
}
|
||||
|
||||
public static class GradleLogbackAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent event) {
|
||||
ThrowableProxy throwableProxy =
|
||||
event.getThrowableProxy() instanceof ThrowableProxy ? (ThrowableProxy)event.getThrowableProxy() : null;
|
||||
Throwable throwable = throwableProxy == null ? null : throwableProxy.getThrowable();
|
||||
|
||||
switch (event.getLevel().toInt()) {
|
||||
case Level.ALL_INT:
|
||||
case Level.TRACE_INT:
|
||||
case Level.DEBUG_INT:
|
||||
LOG.debug(event.getFormattedMessage(), throwable);
|
||||
break;
|
||||
case Level.INFO_INT:
|
||||
LOG.info(event.getFormattedMessage(), throwable);
|
||||
break;
|
||||
case Level.WARN_INT:
|
||||
LOG.warn(event.getFormattedMessage(), throwable);
|
||||
break;
|
||||
case Level.ERROR_INT:
|
||||
LOG.error(event.getFormattedMessage(), throwable);
|
||||
break;
|
||||
case Level.OFF_INT:
|
||||
break;
|
||||
default:
|
||||
LOG.debug(event.getFormattedMessage(), throwable);
|
||||
break;
|
||||
}
|
||||
|
||||
if (NonCancellableConsumerConnectionAdapter.class.getName().equals(event.getLoggerName()) &&
|
||||
GRADLE_PROVIDER_DOES_NOT_SUPPORT_CANCELLATION_MESSAGE.equals(event.getMessage())) {
|
||||
// see org.gradle.tooling.internal.consumer.connection.NonCancellableConsumerConnectionAdapter#handleCancellationPreOperation
|
||||
|
||||
ExternalSystemProcessingManager processingManager = ServiceManager.getService(ExternalSystemProcessingManager.class);
|
||||
final List<ExternalSystemTask> canceledTasks =
|
||||
processingManager
|
||||
.findTasksOfState(GradleConstants.SYSTEM_ID, ExternalSystemTaskState.CANCELING, ExternalSystemTaskState.CANCELED);
|
||||
for (ExternalSystemTask canceledTask : canceledTasks) {
|
||||
final Project project = canceledTask.getId().findProject();
|
||||
if (project != null) {
|
||||
String errorMessage = String.format("%s <a href=\"%s\">Open Gradle settings</a>",
|
||||
"Configured version of Gradle does not support cancellation. Please, use Gradle 2.1 or newer.\n",
|
||||
OpenGradleSettingsCallback.ID);
|
||||
NotificationData notification = new NotificationData(
|
||||
"Gradle supports cancellation since 2.1 version", errorMessage, NotificationCategory.WARNING,
|
||||
NotificationSource.PROJECT_SYNC);
|
||||
notification.setListener(OpenGradleSettingsCallback.ID, new OpenGradleSettingsCallback(project));
|
||||
notification.setBalloonNotification(true);
|
||||
ExternalSystemNotificationManager.getInstance(project).showNotification(GradleConstants.SYSTEM_ID, notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -55,10 +55,6 @@ public class ProjectImportAction implements BuildAction<ProjectImportAction.AllM
|
||||
}
|
||||
|
||||
AllModels allModels = new AllModels(ideaProject);
|
||||
|
||||
// TODO ask gradle guys why there is always null got for BuildEnvironment model
|
||||
//allModels.setBuildEnvironment(controller.findModel(BuildEnvironment.class));
|
||||
|
||||
addExtraProject(controller, allModels, null);
|
||||
for (IdeaModule module : ideaProject.getModules()) {
|
||||
addExtraProject(controller, allModels, module);
|
||||
|
||||
+30
-1
@@ -207,7 +207,36 @@ class InProcessGroovyc implements GroovycFlavor {
|
||||
return pair.second;
|
||||
}
|
||||
|
||||
final ClassDependencyLoader checkWellFormed = new ClassDependencyLoader();
|
||||
final ClassDependencyLoader checkWellFormed = new ClassDependencyLoader() {
|
||||
@Override
|
||||
protected void loadClassDependencies(Class aClass) throws ClassNotFoundException {
|
||||
if (!isCompilerCoreClass(aClass.getName()) || !(aClass.getClassLoader() instanceof UrlClassLoader)) {
|
||||
super.loadClassDependencies(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCompilerCoreClass(String name) {
|
||||
if (name.startsWith("groovyjarjar")) {
|
||||
return true;
|
||||
}
|
||||
if (name.startsWith("org.codehaus.groovy.")) {
|
||||
String tail = name.substring("org.codehaus.groovy.".length());
|
||||
if (tail.startsWith("ast") ||
|
||||
tail.startsWith("classgen") ||
|
||||
tail.startsWith("tools.javac") ||
|
||||
tail.startsWith("antlr") ||
|
||||
tail.startsWith("vmplugin") ||
|
||||
tail.startsWith("reflection") ||
|
||||
tail.startsWith("control")) {
|
||||
return true;
|
||||
}
|
||||
if (tail.startsWith("runtime") && name.contains("GroovyMethods")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
UrlClassLoader groovyAllLoader = UrlClassLoader.build().
|
||||
urls(toUrls(ContainerUtil.concat(GroovyBuilder.getGroovyRtRoots(), Collections.singletonList(groovyAll)))).allowLock().
|
||||
useCache(ourLoaderCachePool, new UrlClassLoader.CachingCondition() {
|
||||
|
||||
+20
-19
@@ -23,73 +23,74 @@ import java.util.Set;
|
||||
* @author peter
|
||||
*/
|
||||
public class ClassDependencyLoader {
|
||||
private final Set<Class> myVisited = new HashSet<Class>();
|
||||
|
||||
/**
|
||||
* @param aClass
|
||||
* @return aClass
|
||||
* @throws ClassNotFoundException when any of the classes can't be loaded, that's referenced in aClass' fields, methods etc. recursively
|
||||
* @throws ClassNotFoundException when any of the classes can't be loaded, that's referenced in aClass' fields, methods etc. recursively
|
||||
*/
|
||||
public Class loadDependencies(Class aClass) throws ClassNotFoundException {
|
||||
loadClassDependencies(aClass, new HashSet<Class>());
|
||||
loadClassDependencies(aClass);
|
||||
return aClass;
|
||||
}
|
||||
|
||||
private void loadTypeDependencies(Type aClass, Set<Class> visited) throws ClassNotFoundException {
|
||||
private void loadTypeDependencies(Type aClass) throws ClassNotFoundException {
|
||||
if (aClass instanceof Class) {
|
||||
loadClassDependencies((Class)aClass, visited);
|
||||
loadClassDependencies((Class)aClass);
|
||||
}
|
||||
else if (aClass instanceof ParameterizedType) {
|
||||
loadTypeDependencies(((ParameterizedType)aClass).getOwnerType(), visited);
|
||||
loadTypeDependencies(((ParameterizedType)aClass).getOwnerType());
|
||||
for (Type type : ((ParameterizedType)aClass).getActualTypeArguments()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
}
|
||||
else if (aClass instanceof WildcardType) {
|
||||
for (Type type : ((WildcardType)aClass).getLowerBounds()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
for (Type type : ((WildcardType)aClass).getUpperBounds()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
}
|
||||
else if (aClass instanceof GenericArrayType) {
|
||||
loadTypeDependencies(((GenericArrayType)aClass).getGenericComponentType(), visited);
|
||||
loadTypeDependencies(((GenericArrayType)aClass).getGenericComponentType());
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadClassDependencies(Class aClass, Set<Class> visited) throws ClassNotFoundException {
|
||||
protected void loadClassDependencies(Class aClass) throws ClassNotFoundException {
|
||||
String name = aClass.getName();
|
||||
if (visited.add(aClass)) {
|
||||
if (myVisited.add(aClass)) {
|
||||
try {
|
||||
for (Method method : aClass.getDeclaredMethods()) {
|
||||
loadTypeDependencies(method.getGenericReturnType(), visited);
|
||||
loadTypeDependencies(method.getGenericReturnType());
|
||||
for (Type type : method.getGenericExceptionTypes()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
for (Type type : method.getGenericParameterTypes()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
}
|
||||
for (Constructor method : aClass.getDeclaredConstructors()) {
|
||||
for (Type type : method.getGenericExceptionTypes()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
for (Type type : method.getGenericParameterTypes()) {
|
||||
loadTypeDependencies(type, visited);
|
||||
loadTypeDependencies(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (Field field : aClass.getDeclaredFields()) {
|
||||
loadTypeDependencies(field.getGenericType(), visited);
|
||||
loadTypeDependencies(field.getGenericType());
|
||||
}
|
||||
|
||||
Type superclass = aClass.getGenericSuperclass();
|
||||
if (superclass != null) {
|
||||
loadClassDependencies(aClass, visited);
|
||||
loadClassDependencies(aClass);
|
||||
}
|
||||
|
||||
for (Type intf : aClass.getGenericInterfaces()) {
|
||||
loadTypeDependencies(intf, visited);
|
||||
loadTypeDependencies(intf);
|
||||
}
|
||||
|
||||
aClass.getAnnotations();
|
||||
|
||||
@@ -468,9 +468,9 @@ public class DependentGroovycRunner {
|
||||
static GroovyClassLoader buildClassLoaderFor(final CompilerConfiguration compilerConfiguration, final AstAwareResourceLoader resourceLoader) {
|
||||
final ClassDependencyLoader checkWellFormed = new ClassDependencyLoader() {
|
||||
@Override
|
||||
protected void loadClassDependencies(Class aClass, Set<Class> visited) throws ClassNotFoundException {
|
||||
protected void loadClassDependencies(Class aClass) throws ClassNotFoundException {
|
||||
if (resourceLoader.getSourceFile(aClass.getName()) == null) return;
|
||||
super.loadClassDependencies(aClass, visited);
|
||||
super.loadClassDependencies(aClass);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+4
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -44,16 +44,12 @@ public class BasicBlock implements IGraphNode {
|
||||
|
||||
private List<BasicBlock> succs = new ArrayList<BasicBlock>();
|
||||
|
||||
private List<Integer> instrOldOffsets = new ArrayList<Integer>();
|
||||
private final List<Integer> instrOldOffsets = new ArrayList<Integer>();
|
||||
|
||||
private List<BasicBlock> predExceptions = new ArrayList<BasicBlock>();
|
||||
|
||||
private List<BasicBlock> succExceptions = new ArrayList<BasicBlock>();
|
||||
|
||||
|
||||
public BasicBlock() {
|
||||
}
|
||||
|
||||
public BasicBlock(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
@@ -63,11 +59,10 @@ public class BasicBlock implements IGraphNode {
|
||||
// *****************************************************************************
|
||||
|
||||
public Object clone() {
|
||||
BasicBlock block = new BasicBlock(id);
|
||||
|
||||
BasicBlock block = new BasicBlock();
|
||||
block.id = id;
|
||||
block.setSeq(seq.clone());
|
||||
block.setInstrOldOffsets(new ArrayList<Integer>(instrOldOffsets));
|
||||
block.instrOldOffsets.addAll(instrOldOffsets);
|
||||
|
||||
return block;
|
||||
}
|
||||
@@ -220,10 +215,6 @@ public class BasicBlock implements IGraphNode {
|
||||
return instrOldOffsets;
|
||||
}
|
||||
|
||||
public void setInstrOldOffsets(List<Integer> instrInds) {
|
||||
this.instrOldOffsets = instrInds;
|
||||
}
|
||||
|
||||
public List<? extends IGraphNode> getPredecessors() {
|
||||
List<BasicBlock> lst = new ArrayList<BasicBlock>(preds);
|
||||
lst.addAll(predExceptions);
|
||||
|
||||
+5
-10
@@ -296,7 +296,7 @@ public class ControlFlowGraph implements CodeConstants {
|
||||
VBStyleCollection<BasicBlock, Integer> col = new VBStyleCollection<BasicBlock, Integer>();
|
||||
|
||||
InstructionSequence currseq = null;
|
||||
ArrayList<Integer> lstOffs = null;
|
||||
List<Integer> lstOffs = null;
|
||||
|
||||
int len = startblock.length;
|
||||
short counter = 0;
|
||||
@@ -306,14 +306,11 @@ public class ControlFlowGraph implements CodeConstants {
|
||||
for (int i = 0; i < len; i++) {
|
||||
|
||||
if (startblock[i] == 1) {
|
||||
currentBlock = new BasicBlock();
|
||||
currentBlock.id = ++counter;
|
||||
currentBlock = new BasicBlock(++counter);
|
||||
|
||||
currseq = new SimpleInstructionSequence();
|
||||
lstOffs = new ArrayList<Integer>();
|
||||
currseq = currentBlock.getSeq();
|
||||
lstOffs = currentBlock.getInstrOldOffsets();
|
||||
|
||||
currentBlock.setSeq(currseq);
|
||||
currentBlock.setInstrOldOffsets(lstOffs);
|
||||
col.addWithKey(currentBlock, currentBlock.id);
|
||||
|
||||
blockoffset = instrseq.getOffset(i);
|
||||
@@ -766,9 +763,7 @@ public class ControlFlowGraph implements CodeConstants {
|
||||
|
||||
first = blocks.get(0);
|
||||
|
||||
last = new BasicBlock();
|
||||
last.id = ++last_id;
|
||||
last.setSeq(new SimpleInstructionSequence());
|
||||
last = new BasicBlock(++last_id);
|
||||
|
||||
for (BasicBlock block : blocks) {
|
||||
if (block.getSuccs().isEmpty()) {
|
||||
|
||||
+5
-1
@@ -101,6 +101,8 @@ public class BytecodeMappingTracer {
|
||||
}
|
||||
|
||||
Map<Integer, Integer> res = new HashMap<Integer, Integer>();
|
||||
|
||||
// first match offsets from line number table
|
||||
int[] data = lineNumberTable.getRawData();
|
||||
for (int i = 0; i < data.length; i += 2) {
|
||||
int originalOffset = data[i];
|
||||
@@ -113,9 +115,11 @@ public class BytecodeMappingTracer {
|
||||
unmappedLines.add(originalLine);
|
||||
}
|
||||
}
|
||||
|
||||
// now match offsets from decompiler mapping
|
||||
for (Entry<Integer, Integer> entry : mapping.entrySet()) {
|
||||
int originalLine = lineNumberTable.findLineNumber(entry.getKey());
|
||||
if (originalLine > -1) {
|
||||
if (originalLine > -1 && !res.containsKey(originalLine)) {
|
||||
res.put(originalLine, entry.getValue());
|
||||
unmappedLines.remove(originalLine);
|
||||
}
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -889,13 +889,16 @@ public class FinallyProcessor {
|
||||
if (seqPattern.length() < seqSample.length()) { // split in two blocks
|
||||
|
||||
SimpleInstructionSequence seq = new SimpleInstructionSequence();
|
||||
LinkedList<Integer> oldOffsets = new LinkedList<Integer>();
|
||||
for (int i = seqSample.length() - 1; i >= seqPattern.length(); i--) {
|
||||
seq.addInstruction(0, seqSample.getInstr(i), -1);
|
||||
oldOffsets.addFirst(sample.getOldOffset(i));
|
||||
seqSample.removeInstruction(i);
|
||||
}
|
||||
|
||||
BasicBlock newblock = new BasicBlock(++graph.last_id);
|
||||
newblock.setSeq(seq);
|
||||
newblock.getInstrOldOffsets().addAll(oldOffsets);
|
||||
|
||||
List<BasicBlock> lstTemp = new ArrayList<BasicBlock>();
|
||||
lstTemp.addAll(sample.getSuccs());
|
||||
@@ -1038,7 +1041,7 @@ public class FinallyProcessor {
|
||||
|
||||
// new empty block
|
||||
BasicBlock emptyblock = new BasicBlock(++graph.last_id);
|
||||
emptyblock.setSeq(new SimpleInstructionSequence());
|
||||
|
||||
graph.getBlocks().addWithKey(emptyblock, emptyblock.id);
|
||||
|
||||
// add to ranges if necessary
|
||||
|
||||
@@ -12,9 +12,9 @@ class i implements bg {
|
||||
private final b b;
|
||||
|
||||
i(b var1, j var2) {
|
||||
this.b = var1;
|
||||
this.b = var1;// 1
|
||||
this.a = var2;
|
||||
}// 1
|
||||
}
|
||||
|
||||
public void a(c var1, k var2, boolean var3) {
|
||||
File var4 = this.a.b().a(var1);// 2
|
||||
@@ -50,7 +50,7 @@ class 'a/a/a/a/e/f/i' {
|
||||
|
||||
Lines mapping:
|
||||
0 <-> 25
|
||||
1 <-> 17
|
||||
1 <-> 15
|
||||
2 <-> 20
|
||||
3 <-> 21
|
||||
4 <-> 22
|
||||
|
||||
@@ -13,7 +13,7 @@ public class TestClassLoop {
|
||||
while(true) {
|
||||
try {
|
||||
if(!var0) {// 33
|
||||
return;
|
||||
return;// 34
|
||||
}
|
||||
} finally {
|
||||
System.out.println("1");// 38
|
||||
@@ -37,7 +37,7 @@ public class TestClassLoop {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("4");
|
||||
System.out.println("4");// 58
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,7 @@ class 'pkg/TestClassLoop' {
|
||||
4 10
|
||||
d 10
|
||||
f 14
|
||||
1a 15
|
||||
26 18
|
||||
27 18
|
||||
2a 18
|
||||
@@ -71,6 +72,9 @@ class 'pkg/TestClassLoop' {
|
||||
2a 33
|
||||
2d 33
|
||||
2f 33
|
||||
37 39
|
||||
3a 39
|
||||
3c 39
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,13 +82,13 @@ Lines mapping:
|
||||
23 <-> 6
|
||||
29 <-> 11
|
||||
33 <-> 15
|
||||
34 <-> 16
|
||||
38 <-> 19
|
||||
45 <-> 25
|
||||
49 <-> 30
|
||||
52 <-> 33
|
||||
53 <-> 34
|
||||
58 <-> 40
|
||||
Not mapped:
|
||||
34
|
||||
39
|
||||
54
|
||||
58
|
||||
|
||||
@@ -50,6 +50,7 @@ class 'pkg/TestClassVar' {
|
||||
20 11
|
||||
26 12
|
||||
29 12
|
||||
2e 7
|
||||
34 18
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ public enum TestEnum {
|
||||
}// 30
|
||||
|
||||
private TestEnum() {
|
||||
this("?");
|
||||
}// 34
|
||||
this("?");// 34
|
||||
}
|
||||
|
||||
private TestEnum(@Deprecated String var3) {
|
||||
this.s = var3;
|
||||
}// 35
|
||||
this.s = var3;// 35
|
||||
}
|
||||
}
|
||||
|
||||
class 'pkg/TestEnum$1' {
|
||||
@@ -59,5 +59,5 @@ Lines mapping:
|
||||
22 <-> 7
|
||||
27 <-> 12
|
||||
30 <-> 18
|
||||
34 <-> 22
|
||||
35 <-> 26
|
||||
34 <-> 21
|
||||
35 <-> 25
|
||||
|
||||
@@ -36,7 +36,7 @@ public class TestTryCatchFinally {
|
||||
System.out.println("Finally");// 55
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;// 56
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,13 +67,16 @@ class 'pkg/TestTryCatchFinally' {
|
||||
method 'test (Ljava/lang/String;)I' {
|
||||
1 30
|
||||
4 30
|
||||
e 31
|
||||
10 33
|
||||
1a 33
|
||||
23 33
|
||||
26 33
|
||||
31 38
|
||||
34 35
|
||||
35 35
|
||||
38 35
|
||||
3f 38
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +93,11 @@ Lines mapping:
|
||||
51 <-> 31
|
||||
53 <-> 34
|
||||
55 <-> 36
|
||||
56 <-> 39
|
||||
57 <-> 39
|
||||
Not mapped:
|
||||
25
|
||||
28
|
||||
32
|
||||
35
|
||||
52
|
||||
56
|
||||
57
|
||||
|
||||
+9
@@ -35,6 +35,7 @@ import java.util.List;
|
||||
|
||||
public class ResourceBundleImpl extends ResourceBundle {
|
||||
@NotNull private final PropertiesFile myDefaultPropertiesFile;
|
||||
private boolean myValid = true;
|
||||
|
||||
public ResourceBundleImpl(@NotNull final PropertiesFile defaultPropertiesFile) {
|
||||
myDefaultPropertiesFile = defaultPropertiesFile;
|
||||
@@ -94,6 +95,14 @@ public class ResourceBundleImpl extends ResourceBundle {
|
||||
return myDefaultPropertiesFile.getProject();
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return myValid;
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
myValid = false;
|
||||
}
|
||||
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
+3
@@ -215,6 +215,9 @@ public class ResourceBundleManager implements PersistentStateComponent<ResourceB
|
||||
LOG.assertTrue(state != null);
|
||||
myState.getCustomResourceBundles().remove(state);
|
||||
} else {
|
||||
if (EmptyResourceBundle.getInstance() != resourceBundle) {
|
||||
((ResourceBundleImpl) resourceBundle).invalidate();
|
||||
}
|
||||
for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
|
||||
final VirtualFile file = propertiesFile.getContainingFile().getVirtualFile();
|
||||
myState.getDissociatedFiles().add(file.getUrl());
|
||||
|
||||
+7
-1
@@ -26,6 +26,7 @@ import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.lang.properties.*;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.editor.ResourceBundleAsVirtualFile;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
@@ -104,6 +105,11 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
|
||||
if (!super.validate()) {
|
||||
return false;
|
||||
}
|
||||
return Comparing.equal(getValue().getDefaultPropertiesFile().getResourceBundle(), getValue());
|
||||
final ResourceBundle newBundle = getValue().getDefaultPropertiesFile().getResourceBundle();
|
||||
final ResourceBundle currentBundle = getValue();
|
||||
if (!Comparing.equal(newBundle, currentBundle)) {
|
||||
return false;
|
||||
}
|
||||
return !(currentBundle instanceof ResourceBundleImpl) || ((ResourceBundleImpl)currentBundle).isValid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class PyCCEduProjectTemplate extends EduProjectTemplate {
|
||||
StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PyCCProjectGenerator.generateProject(project, baseDir, panel.getName(), panel.getAuthor(), panel.getDescription());
|
||||
PyCCProjectGenerator.generateProject(project, baseDir, panel.getName(), panel.getAuthors(), panel.getDescription());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+4
-4
@@ -55,17 +55,17 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire
|
||||
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
|
||||
@Nullable Object settings, @NotNull Module module) {
|
||||
generateProject(project, baseDir, mySettingsPanel.getName(),
|
||||
mySettingsPanel.getAuthor(), mySettingsPanel.getDescription());
|
||||
mySettingsPanel.getAuthors(), mySettingsPanel.getDescription());
|
||||
}
|
||||
|
||||
public static void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
|
||||
@NotNull final String name, @NotNull final String author,
|
||||
@NotNull final String name, @NotNull final String[] authors,
|
||||
@NotNull final String description) {
|
||||
|
||||
final CCProjectService service = CCProjectService.getInstance(project);
|
||||
final Course course = new Course();
|
||||
course.setName(name);
|
||||
course.setAuthor(author);
|
||||
course.setAuthors(authors);
|
||||
course.setDescription(description);
|
||||
course.setLanguage("Python");
|
||||
service.setCourse(course);
|
||||
@@ -93,7 +93,7 @@ public class PyCCProjectGenerator extends PythonProjectGenerator implements Dire
|
||||
public ValidationResult validate(@NotNull String s) {
|
||||
String message = "";
|
||||
message = mySettingsPanel.getDescription().isEmpty() ? "Enter description" : message;
|
||||
message = mySettingsPanel.getAuthor().isEmpty() ? "Enter author name" : message;
|
||||
message = mySettingsPanel.getAuthors().length == 0 ? "Enter author name" : message;
|
||||
message = mySettingsPanel.getName().isEmpty() ? "Enter course name" : message;
|
||||
return message.isEmpty() ? ValidationResult.OK : new ValidationResult(message);
|
||||
}
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator imp
|
||||
}
|
||||
|
||||
public List<CourseInfo> getCourses() {
|
||||
return myGenerator.getCourses();
|
||||
return myGenerator.getCourses(false);
|
||||
}
|
||||
|
||||
public void setSelectedCourse(CourseInfo course) {
|
||||
|
||||
+2
-2
@@ -78,12 +78,12 @@ public class CCChangeCourseInfo extends DumbAwareAction {
|
||||
if (directory != null && !project.getBaseDir().equals(directory.getVirtualFile())) {
|
||||
return;
|
||||
}
|
||||
CCNewProjectPanel panel = new CCNewProjectPanel(course.getName(), course.getAuthor(), course.getDescription());
|
||||
CCNewProjectPanel panel = new CCNewProjectPanel(course.getName(), Course.getAuthorsString(course.getAuthors()), course.getDescription());
|
||||
ChangeCourseInfoDialog changeCourseInfoDialog =
|
||||
new ChangeCourseInfoDialog(project, panel);
|
||||
changeCourseInfoDialog.show();
|
||||
if (changeCourseInfoDialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
|
||||
course.setAuthor(panel.getAuthor());
|
||||
course.setAuthors(panel.getAuthors());
|
||||
course.setName(panel.getName());
|
||||
course.setDescription(panel.getDescription());
|
||||
ProjectView.getInstance(project).refresh();
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class CCPushLesson extends DumbAwareAction {
|
||||
if (course == null) {
|
||||
return;
|
||||
}
|
||||
PsiDirectory lessonDir = DirectoryChooserUtil.getOrChooseDirectory(view);;
|
||||
PsiDirectory lessonDir = DirectoryChooserUtil.getOrChooseDirectory(view);
|
||||
if (lessonDir == null || !lessonDir.getName().contains("lesson")) {
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-2
@@ -51,8 +51,8 @@ public class CCNewProjectPanel {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getAuthor() {
|
||||
return StringUtil.notNullize(myAuthorField.getText());
|
||||
public String[] getAuthors() {
|
||||
return StringUtil.splitByLines(StringUtil.notNullize(myAuthorField.getText()));
|
||||
}
|
||||
|
||||
public void registerValidators(FacetValidatorsManager manager) {
|
||||
|
||||
+10
-7
@@ -211,10 +211,13 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
writer = new PrintWriter(cashFile);
|
||||
for (CourseInfo courseInfo : myCourses) {
|
||||
String line = String
|
||||
.format("name=%s author=%s description=%s", courseInfo.getName(), courseInfo.getAuthor(),
|
||||
courseInfo.getDescription());
|
||||
writer.println(line);
|
||||
final List<CourseInfo.Instructor> instructors = courseInfo.getInstructors();
|
||||
StringBuilder builder = new StringBuilder("name=").append(courseInfo.getName()).append("description=").append(
|
||||
courseInfo.getDescription());
|
||||
for (CourseInfo.Instructor instructor : instructors) {
|
||||
builder.append("instructor=").append(instructor.getName());
|
||||
}
|
||||
writer.println(builder.toString());
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
@@ -228,12 +231,12 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
public List<CourseInfo> getCourses() {
|
||||
if (!myCourses.isEmpty()) {
|
||||
public List<CourseInfo> getCourses(boolean force) {
|
||||
if (force || myCourses.isEmpty()) {
|
||||
myCourses = EduStepicConnector.getCourses();
|
||||
return myCourses;
|
||||
}
|
||||
else {
|
||||
myCourses = EduStepicConnector.getCourses();
|
||||
return myCourses;
|
||||
}
|
||||
}
|
||||
|
||||
+67
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.learning.ui.StudyNewProjectPanel">
|
||||
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myContentPanel" layout-manager="GridLayoutManager" row-count="4" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
@@ -67,6 +67,72 @@
|
||||
<verticalTextPosition value="1"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="f583f" binding="myHideablePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="b4a52" binding="myLoginPanel" layout-manager="GridBagLayout">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="f0dd0" class="javax.swing.JPasswordField" binding="myPasswordField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
<gridbag weightx="1.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="8d976" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Password:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="56bf1" class="javax.swing.JTextField" binding="myLoginField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
<gridbag weightx="1.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="fb0e2" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="E-mail:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5f574" class="javax.swing.JButton" binding="myLogInButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<gridbag weightx="0.0" weighty="1.0"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Log in"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<vspacer id="9a0a">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+46
-19
@@ -3,9 +3,12 @@ package com.jetbrains.edu.learning.ui;
|
||||
import com.intellij.facet.ui.FacetValidatorsManager;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ui.HideableDecorator;
|
||||
import com.jetbrains.edu.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.stepic.CourseInfo;
|
||||
import com.jetbrains.edu.stepic.EduStepicConnector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -19,6 +22,7 @@ import java.util.List;
|
||||
* data: 7/31/14.
|
||||
*/
|
||||
public class StudyNewProjectPanel{
|
||||
private final HideableDecorator myDecorator;
|
||||
private List<CourseInfo> myAvailableCourses = new ArrayList<CourseInfo>();
|
||||
private JComboBox myCoursesComboBox;
|
||||
private JButton myRefreshButton;
|
||||
@@ -27,6 +31,11 @@ public class StudyNewProjectPanel{
|
||||
private JLabel myDescriptionLabel;
|
||||
private JLabel myLabel;
|
||||
private JPanel myInfoPanel;
|
||||
private JPanel myHideablePanel;
|
||||
private JPanel myLoginPanel;
|
||||
private JPasswordField myPasswordField;
|
||||
private JTextField myLoginField;
|
||||
private JButton myLogInButton;
|
||||
private final StudyProjectGenerator myGenerator;
|
||||
private static final String CONNECTION_ERROR = "<html>Failed to download courses.<br>Check your Internet connection.</html>";
|
||||
private static final String INVALID_COURSE = "Selected course is invalid";
|
||||
@@ -34,7 +43,7 @@ public class StudyNewProjectPanel{
|
||||
|
||||
public StudyNewProjectPanel(StudyProjectGenerator generator) {
|
||||
myGenerator = generator;
|
||||
myAvailableCourses = myGenerator.getCourses();
|
||||
myAvailableCourses = myGenerator.getCourses(false);
|
||||
if (myAvailableCourses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
}
|
||||
@@ -42,7 +51,7 @@ public class StudyNewProjectPanel{
|
||||
for (CourseInfo courseInfo : myAvailableCourses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
myAuthorLabel.setText("Author: " + StudyUtils.getFirst(myAvailableCourses).getAuthor());
|
||||
myAuthorLabel.setText("Author: " + Course.getAuthorsString(StudyUtils.getFirst(myAvailableCourses).getInstructors()));
|
||||
myDescriptionLabel.setText(StudyUtils.getFirst(myAvailableCourses).getDescription());
|
||||
//setting the first course in list as selected
|
||||
myGenerator.setSelectedCourse(StudyUtils.getFirst(myAvailableCourses));
|
||||
@@ -53,12 +62,26 @@ public class StudyNewProjectPanel{
|
||||
myRefreshButton.setIcon(AllIcons.Actions.Refresh);
|
||||
|
||||
myLabel.setPreferredSize(new JLabel("Project name").getPreferredSize());
|
||||
myDecorator = new HideableDecorator(myHideablePanel, "Credentials", false);
|
||||
myDecorator.setOn(false);
|
||||
myDecorator.setContentComponent(myLoginPanel);
|
||||
|
||||
}
|
||||
|
||||
private void initListeners() {
|
||||
|
||||
myRefreshButton.addActionListener(new RefreshActionListener());
|
||||
myCoursesComboBox.addActionListener(new CourseSelectedListener());
|
||||
myLogInButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final boolean isSuccess = EduStepicConnector.login(myLoginField.getText(), String.valueOf(myPasswordField.getPassword()));
|
||||
if (!isSuccess) {
|
||||
setError("Failed to log in");
|
||||
return;
|
||||
}
|
||||
refreshCoursesList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setError(@NotNull final String errorMessage) {
|
||||
@@ -92,24 +115,28 @@ public class StudyNewProjectPanel{
|
||||
private class RefreshActionListener implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final List<CourseInfo> courses = myGenerator.getCourses();
|
||||
if (courses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
return;
|
||||
}
|
||||
myCoursesComboBox.removeAllItems();
|
||||
|
||||
for (CourseInfo courseInfo : courses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
myGenerator.setSelectedCourse(StudyUtils.getFirst(courses));
|
||||
|
||||
myGenerator.setCourses(courses);
|
||||
myAvailableCourses = courses;
|
||||
myGenerator.flushCache();
|
||||
refreshCoursesList();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCoursesList() {
|
||||
final List<CourseInfo> courses = myGenerator.getCourses(true);
|
||||
if (courses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
return;
|
||||
}
|
||||
myCoursesComboBox.removeAllItems();
|
||||
|
||||
for (CourseInfo courseInfo : courses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
myGenerator.setSelectedCourse(StudyUtils.getFirst(courses));
|
||||
|
||||
myGenerator.setCourses(courses);
|
||||
myAvailableCourses = courses;
|
||||
myGenerator.flushCache();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles selecting course in combo box
|
||||
@@ -126,7 +153,7 @@ public class StudyNewProjectPanel{
|
||||
myDescriptionLabel.setText("");
|
||||
return;
|
||||
}
|
||||
myAuthorLabel.setText("Author: " + selectedCourse.getAuthor());
|
||||
myAuthorLabel.setText("Author: " + Course.getAuthorsString(selectedCourse.getInstructors()));
|
||||
myCoursesComboBox.removeItem(CourseInfo.INVALID_COURSE);
|
||||
myDescriptionLabel.setText(selectedCourse.getDescription());
|
||||
myGenerator.setSelectedCourse(selectedCourse);
|
||||
|
||||
+1
-2
@@ -36,8 +36,7 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
|
||||
}
|
||||
String courseName = UIUtil.toHtml("<h1>" + course.getName() + "</h1>", 10);
|
||||
String description = UIUtil.toHtml(course.getDescription(), 5);
|
||||
String author = taskManager.getCourse().getAuthor();
|
||||
String authorLabel = UIUtil.toHtml("<b>Author: </b>" + author, 5);
|
||||
String authorLabel = UIUtil.toHtml("<b>Author: </b>" + Course.getAuthorsString(course.getAuthors()), 5);
|
||||
contentPanel.add(new JLabel(courseName));
|
||||
contentPanel.add(new JLabel(authorLabel));
|
||||
contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
|
||||
@@ -3,8 +3,11 @@ package com.jetbrains.edu.courseFormat;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.edu.EduNames;
|
||||
import com.jetbrains.edu.EduUtils;
|
||||
import com.jetbrains.edu.stepic.CourseInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -17,7 +20,7 @@ public class Course {
|
||||
@Expose private String description;
|
||||
@Expose private String name;
|
||||
private String myCourseDirectory = "";
|
||||
@Expose private String author="";
|
||||
@Expose private List<CourseInfo.Instructor> authors = new ArrayList<CourseInfo.Instructor>();
|
||||
private boolean myUpToDate;
|
||||
|
||||
@Expose @SerializedName("language")
|
||||
@@ -56,12 +59,25 @@ public class Course {
|
||||
return lessons.get(lessonIndex);
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
@NotNull
|
||||
public List<CourseInfo.Instructor> getAuthors() {
|
||||
return authors;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
public static String getAuthorsString(@NotNull List<CourseInfo.Instructor> authors) {
|
||||
return StringUtil.join(authors, new Function<CourseInfo.Instructor, String>() {
|
||||
@Override
|
||||
public String fun(CourseInfo.Instructor instructor) {
|
||||
return instructor.getName();
|
||||
}
|
||||
}, ", ");
|
||||
}
|
||||
|
||||
public void setAuthors(String[] authors) {
|
||||
this.authors = new ArrayList<CourseInfo.Instructor>();
|
||||
for (String name : authors) {
|
||||
this.authors.add(new CourseInfo.Instructor(name));
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -107,4 +123,8 @@ public class Course {
|
||||
public void setLanguage(@NotNull final String language) {
|
||||
myLanguage = language;
|
||||
}
|
||||
|
||||
public void setAuthors(List<CourseInfo.Instructor> instructors) {
|
||||
this.authors = instructors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.jetbrains.edu.stepic;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -19,22 +21,18 @@ public class CourseInfo {
|
||||
//course type in format "pycharm <language>"
|
||||
private String myType;
|
||||
|
||||
private String myAuthor;
|
||||
public static CourseInfo INVALID_COURSE = new CourseInfo("", "", "", "");
|
||||
@SerializedName("instructors")
|
||||
List<Instructor> myInstructors = new ArrayList<Instructor>();
|
||||
|
||||
public CourseInfo(String name, String author, String description, String type) {
|
||||
myName = name;
|
||||
myAuthor = author;
|
||||
myDescription = description;
|
||||
myType = type;
|
||||
}
|
||||
public static CourseInfo INVALID_COURSE = new CourseInfo();
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return myAuthor;
|
||||
@NotNull
|
||||
public List<Instructor> getInstructors() {
|
||||
return myInstructors;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
@@ -55,15 +53,27 @@ public class CourseInfo {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CourseInfo that = (CourseInfo)o;
|
||||
return that.getName().equals(myName) && that.getAuthor().equals(myAuthor)
|
||||
if (that.getName() == null || that.getDescription() == null) return false;
|
||||
return that.getName().equals(myName)
|
||||
&& that.getDescription().equals(myDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myName != null ? myName.hashCode() : 0;
|
||||
result = 31 * result + (myAuthor != null ? myAuthor.hashCode() : 0);
|
||||
result = 31 * result + (myDescription != null ? myDescription.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class Instructor {
|
||||
String name;
|
||||
|
||||
public Instructor(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,89 +8,164 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.io.HttpRequests;
|
||||
import com.intellij.util.net.ssl.CertificateManager;
|
||||
import com.jetbrains.edu.EduUtils;
|
||||
import com.jetbrains.edu.courseFormat.Course;
|
||||
import com.jetbrains.edu.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.courseFormat.Task;
|
||||
import com.jetbrains.edu.courseFormat.TaskFile;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.cookie.BasicClientCookie;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.protocol.HTTP;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.*;
|
||||
|
||||
public class EduStepicConnector {
|
||||
private static final String stepicApiUrl = "https://stepic.org/api/";
|
||||
private static final String stepicUrl = "https://stepic.org/";
|
||||
private static final String stepicApiUrl = stepicUrl + "api/";
|
||||
private static final Logger LOG = Logger.getInstance(EduStepicConnector.class.getName());
|
||||
private static final String ourDomain = "stepic.org";
|
||||
private static String ourSessionId = "524iethiwju2tjywaqmf7tbwx0p0jk1b";
|
||||
private static String ourCSRFToken = "LJ9n6OyLVA7hxU94dlYWUu65MF51Nx37";
|
||||
private static String ourCSRFToken = "";
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
||||
//this prefix indicates that course can be opened by educational plugin
|
||||
public static final String PYCHARM_PREFIX = "pycharm ";
|
||||
public static final String PYCHARM_PREFIX = "pycharm";
|
||||
private static BasicCookieStore ourCookieStore;
|
||||
|
||||
private EduStepicConnector() {
|
||||
}
|
||||
|
||||
private static <T> T getFromStepic(String link, final Class<T> container) throws IOException {
|
||||
return HttpRequests.request(stepicApiUrl + link).connect(new HttpRequests.RequestProcessor<T>() {
|
||||
@Override
|
||||
public T process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
final BufferedReader reader = request.getReader();
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(reader, container);
|
||||
public static boolean login(@NotNull final String user, @NotNull final String password) {
|
||||
if (ourClient == null || ourCookieStore == null)
|
||||
initializeClient();
|
||||
return postCredentials(user, password);
|
||||
}
|
||||
|
||||
private static void initializeClient() {
|
||||
final HttpGet request = new HttpGet(stepicUrl);
|
||||
request.addHeader(new BasicHeader("referer", "https://stepic.org"));
|
||||
request.addHeader(new BasicHeader("content-type", "application/json"));
|
||||
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext()).setMaxConnPerRoute(100);
|
||||
ourCookieStore = new BasicCookieStore();
|
||||
ourClient = builder.setDefaultCookieStore(ourCookieStore).build();
|
||||
|
||||
try {
|
||||
ourClient.execute(request);
|
||||
saveCSRFToken();
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveCSRFToken() {
|
||||
if (ourCookieStore == null) return;
|
||||
final List<Cookie> cookies = ourCookieStore.getCookies();
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie.getName().equals("csrftoken")) {
|
||||
ourCSRFToken = cookie.getValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean postCredentials(String user, String password) {
|
||||
String url = stepicUrl + "accounts/login/";
|
||||
final HttpPost request = new HttpPost(url);
|
||||
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
|
||||
nvps.add(new BasicNameValuePair("csrfmiddlewaretoken", ourCSRFToken));
|
||||
nvps.add(new BasicNameValuePair("login", user));
|
||||
nvps.add(new BasicNameValuePair("next", "/"));
|
||||
nvps.add(new BasicNameValuePair("password", password));
|
||||
nvps.add(new BasicNameValuePair("remember", "on"));
|
||||
|
||||
try {
|
||||
request.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
setHeaders(request, "application/x-www-form-urlencoded");
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
saveCSRFToken();
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 302) {
|
||||
LOG.error("Failed to login " + EntityUtils.toString(response.getEntity()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static <T> T getFromStepic(String link, final Class<T> container) throws IOException {
|
||||
final HttpGet request = new HttpGet(stepicApiUrl + link);
|
||||
if (ourClient == null) {
|
||||
initializeClient();
|
||||
}
|
||||
setHeaders(request, "application/json");
|
||||
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final String responseString = EntityUtils.toString(response.getEntity());
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(responseString, container);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<CourseInfo> getCourses() {
|
||||
try {
|
||||
return getFromStepic("courses/99", CoursesContainer.class).courses;
|
||||
List<CourseInfo> result = new ArrayList<CourseInfo>();
|
||||
final List<CourseInfo> courseInfos = getFromStepic("courses", CoursesContainer.class).courses;
|
||||
for (CourseInfo info : courseInfos) {
|
||||
final String courseType = info.getType();
|
||||
if (StringUtil.isEmptyOrSpaces(courseType)) continue;
|
||||
final List<String> typeLanguage = StringUtil.split(courseType, " ");
|
||||
if (typeLanguage.size() == 2 && PYCHARM_PREFIX.equals(typeLanguage.get(0))) {
|
||||
result.add(info);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("IOException " + e.getMessage());
|
||||
LOG.error("Cannot load course list " + e.getMessage());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
/*try { // TODO: uncomment
|
||||
return HttpRequests.request(stepicApiUrl + "courses").connect(new HttpRequests.RequestProcessor<List<CourseInfo>>() {
|
||||
|
||||
@Override
|
||||
public List<CourseInfo> process(@NotNull HttpRequests.Request request) throws IOException {
|
||||
final BufferedReader reader = request.getReader();
|
||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(reader, CoursesContainer.class).courses;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("IOException " + e.getMessage());
|
||||
}
|
||||
return null;*/
|
||||
}
|
||||
|
||||
public static Course getCourse(@NotNull final CourseInfo info) {
|
||||
final Course course = new Course();
|
||||
course.setAuthor(info.getAuthor());
|
||||
course.setAuthors(info.getInstructors());
|
||||
course.setDescription(info.getDescription());
|
||||
course.setName(info.getName());
|
||||
String courseType = info.getType();
|
||||
course.setLanguage(courseType.substring(PYCHARM_PREFIX.length()));
|
||||
course.setLanguage(courseType.substring(PYCHARM_PREFIX.length() + 1));
|
||||
course.setUpToDate(true); // TODO: get from stepic
|
||||
try {
|
||||
for (Integer section : info.sections) {
|
||||
@@ -128,7 +203,7 @@ public class EduStepicConnector {
|
||||
private static void createTask(Lesson lesson, Integer s) throws IOException {
|
||||
final Step step = getStep(s);
|
||||
final Task task = new Task();
|
||||
task.setName(step.name);
|
||||
task.setName(step.options != null ? step.options.title : PYCHARM_PREFIX);
|
||||
task.setText(step.text);
|
||||
for (TestFileWrapper wrapper : step.options.test) {
|
||||
task.setTestsTexts(wrapper.name, wrapper.text);
|
||||
@@ -148,23 +223,29 @@ public class EduStepicConnector {
|
||||
}
|
||||
|
||||
|
||||
public static boolean postLesson(Project project, @NotNull final Lesson lesson) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "lessons");
|
||||
final ArrayList<Header> headers = getHeaders(request);
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext());
|
||||
final BasicCookieStore cookieStore = getCookies();
|
||||
final CloseableHttpClient client = builder.setDefaultHeaders(headers).setDefaultCookieStore(cookieStore).build();
|
||||
public static void showLoginDialog() {
|
||||
final LoginDialog dialog = new LoginDialog();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
public static void postLesson(Project project, @NotNull final Lesson lesson) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "lessons");
|
||||
if (ourClient == null) {
|
||||
showLoginDialog();
|
||||
}
|
||||
|
||||
setHeaders(request, "application/json");
|
||||
String requestBody = new Gson().toJson(new LessonWrapper(lesson));
|
||||
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = client.execute(request);
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final String responseString = EntityUtils.toString(response.getEntity());
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 201) {
|
||||
LOG.error("Failed to push " + EntityUtils.toString(response.getEntity()));
|
||||
return false;
|
||||
LOG.error("Failed to push " + responseString);
|
||||
return;
|
||||
}
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, Course.class).getLessons().get(0);
|
||||
for (Task task : lesson.getTaskList()) {
|
||||
@@ -174,56 +255,31 @@ public class EduStepicConnector {
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean postTask(Project project, @NotNull final Task task, int id) {
|
||||
public static void postTask(Project project, @NotNull final Task task, int id) {
|
||||
final HttpPost request = new HttpPost(stepicApiUrl + "step-sources");
|
||||
final ArrayList<Header> headers = getHeaders(request);
|
||||
HttpClientBuilder builder = HttpClients.custom().setSslcontext(CertificateManager.getInstance().getSslContext());
|
||||
final BasicCookieStore cookieStore = getCookies();
|
||||
final CloseableHttpClient client = builder.setDefaultHeaders(headers).setDefaultCookieStore(cookieStore).build();
|
||||
setHeaders(request, "application/json");
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
|
||||
String requestBody = gson.toJson(new StepSourceWrapper(project, task, id));
|
||||
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||
|
||||
try {
|
||||
final CloseableHttpResponse response = client.execute(request);
|
||||
final CloseableHttpResponse response = ourClient.execute(request);
|
||||
final StatusLine line = response.getStatusLine();
|
||||
if (line.getStatusCode() != 201) {
|
||||
LOG.error("Failed to push " + EntityUtils.toString(response.getEntity()));
|
||||
}
|
||||
return line.getStatusCode() == 201;
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static BasicCookieStore getCookies() {
|
||||
final BasicCookieStore cookieStore = new BasicCookieStore();
|
||||
final BasicClientCookie sessionid = new BasicClientCookie("sessionid", ourSessionId);
|
||||
sessionid.setDomain(ourDomain);
|
||||
sessionid.setPath("/");
|
||||
|
||||
cookieStore.addCookie(sessionid);
|
||||
final BasicClientCookie csrfToken = new BasicClientCookie("csrftoken", ourCSRFToken);
|
||||
csrfToken.setDomain(ourDomain);
|
||||
csrfToken.setPath("/");
|
||||
|
||||
cookieStore.addCookie(csrfToken);
|
||||
return cookieStore;
|
||||
}
|
||||
|
||||
private static ArrayList<Header> getHeaders(HttpPost request) {
|
||||
final ArrayList<Header> headers = new ArrayList<Header>();
|
||||
headers.add(new BasicHeader("referer", "https://stepic.org"));
|
||||
headers.add(new BasicHeader("X-CSRFToken", ourCSRFToken));
|
||||
headers.add(new BasicHeader("content-type", "application/json"));
|
||||
request.setHeaders(headers.toArray(new Header[headers.size()]));
|
||||
return headers;
|
||||
private static void setHeaders(@NotNull final HttpRequestBase request, String contentType) {
|
||||
request.addHeader(new BasicHeader("referer", stepicUrl));
|
||||
request.addHeader(new BasicHeader("X-CSRFToken", ourCSRFToken));
|
||||
request.addHeader(new BasicHeader("content-type", contentType));
|
||||
}
|
||||
|
||||
private static class StepContainer {
|
||||
@@ -262,6 +318,7 @@ public class EduStepicConnector {
|
||||
@Override
|
||||
public void run() {
|
||||
final VirtualFile taskDir = task.getTaskDir(project);
|
||||
assert taskDir != null;
|
||||
EduUtils.createStudentFileFromAnswer(project, taskDir, taskDir, entry);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.jetbrains.edu.stepic;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LoginDialog extends DialogWrapper {
|
||||
private final LoginPanel myLoginPanel;
|
||||
|
||||
public LoginDialog() {
|
||||
super(false);
|
||||
myLoginPanel = new LoginPanel(this);
|
||||
setTitle("Login to Stepic");
|
||||
setOKButtonText("Login");
|
||||
init();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{getOKAction(), getCancelAction()};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myLoginPanel.getPanel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHelpId() {
|
||||
return "login_to_stepic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myLoginPanel.getPreferableFocusComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
AuthDataHolder authData = myLoginPanel.getAuthData();
|
||||
final boolean success = EduStepicConnector.login(authData.email, authData.password);
|
||||
if (!success) {
|
||||
setErrorText("Log in failed");
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
public void clearErrors() {
|
||||
setErrorText(null);
|
||||
}
|
||||
|
||||
public static class AuthDataHolder {
|
||||
String email;
|
||||
String password;
|
||||
|
||||
public AuthDataHolder(String login, String password) {
|
||||
email = login;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.jetbrains.edu.stepic.LoginPanel">
|
||||
<grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="174"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusable value="false"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="9b306">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="9edbd" class="javax.swing.JPasswordField" binding="myPasswordField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="300" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="fe9db" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Password:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="c0234" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="E-mail:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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 com.jetbrains.edu.stepic;
|
||||
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
public class LoginPanel {
|
||||
private JPanel myPane;
|
||||
private JTextField myLoginTextField;
|
||||
private JPasswordField myPasswordField;
|
||||
|
||||
public LoginPanel(final LoginDialog dialog) {
|
||||
DocumentListener listener = new DocumentAdapter() {
|
||||
@Override
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
dialog.clearErrors();
|
||||
}
|
||||
};
|
||||
myLoginTextField.getDocument().addDocumentListener(listener);
|
||||
myPasswordField.getDocument().addDocumentListener(listener);
|
||||
}
|
||||
|
||||
public JComponent getPanel() {
|
||||
return myPane;
|
||||
}
|
||||
|
||||
public void setLogin(@Nullable String login) {
|
||||
myLoginTextField.setText(login);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLogin() {
|
||||
return myLoginTextField.getText().trim();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getPassword() {
|
||||
return String.valueOf(myPasswordField.getPassword());
|
||||
}
|
||||
|
||||
public JComponent getPreferableFocusComponent() {
|
||||
return myLoginTextField.isVisible() ? myLoginTextField : myPasswordField;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public LoginDialog.AuthDataHolder getAuthData() {
|
||||
return new LoginDialog.AuthDataHolder(getLogin(), getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,18 +95,25 @@ def _excepthook(exctype, value, tb):
|
||||
return
|
||||
|
||||
frames = []
|
||||
debugger = GetGlobalDebugger()
|
||||
user_frames = []
|
||||
|
||||
while tb:
|
||||
frame = tb.tb_frame
|
||||
if exception_breakpoint.ignore_libraries and not debugger.not_in_scope(frame.f_code.co_filename):
|
||||
user_frames.append(tb.tb_frame)
|
||||
frames.append(tb.tb_frame)
|
||||
tb = tb.tb_next
|
||||
|
||||
thread = threadingCurrentThread()
|
||||
frames_byid = dict([(id(frame),frame) for frame in frames])
|
||||
frame = frames[-1]
|
||||
if exception_breakpoint.ignore_libraries:
|
||||
frame = user_frames[-1]
|
||||
else:
|
||||
frame = frames[-1]
|
||||
thread.additionalInfo.exception = (exctype, value, tb)
|
||||
thread.additionalInfo.pydev_force_stop_at_exception = (frame, frames_byid)
|
||||
thread.additionalInfo.message = exception_breakpoint.qname
|
||||
debugger = GetGlobalDebugger()
|
||||
|
||||
pydevd_tracing.SetTrace(None) #no tracing from here
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
@@ -35,6 +38,19 @@ public enum LanguageLevel {
|
||||
PYTHON34(34, true, false, true, true),
|
||||
PYTHON35(35, true, false, true, true);
|
||||
|
||||
public static List<LanguageLevel> ALL_LEVELS = ImmutableList.<LanguageLevel>builder()
|
||||
.add(PYTHON24)
|
||||
.add(PYTHON25)
|
||||
.add(PYTHON26)
|
||||
.add(PYTHON27)
|
||||
.add(PYTHON30)
|
||||
.add(PYTHON31)
|
||||
.add(PYTHON32)
|
||||
.add(PYTHON33)
|
||||
.add(PYTHON34)
|
||||
.add(PYTHON35)
|
||||
.build();
|
||||
|
||||
private static LanguageLevel DEFAULT2 = PYTHON27;
|
||||
private static LanguageLevel DEFAULT3 = PYTHON34;
|
||||
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.jetbrains.numpy.codeInsight;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.numpy.documentation.NumPyDocString;
|
||||
import com.jetbrains.numpy.documentation.NumPyDocStringParameter;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyExpressionCodeFragmentImpl;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.PyTypeProviderBase;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
@@ -47,6 +50,7 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
// an instance of 'numpy.core.multiarray.dtype', however the type checker isn't able to check it.
|
||||
// 30 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("data-type", "object");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("dtype", "object");
|
||||
// 16 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("scalar", "int or long or float or complex");
|
||||
// 10 occurrences
|
||||
@@ -62,6 +66,8 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("callable", "collections.Callable");
|
||||
// 3 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("number", "int or long or float or complex");
|
||||
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("sequence", "collections.Iterable");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -111,6 +117,7 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
}
|
||||
|
||||
private static boolean isInsideNumPy(@NotNull PsiElement element) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return true;
|
||||
final PsiFile file = element.getContainingFile();
|
||||
if (file != null) {
|
||||
final PyPsiFacade facade = getPsiFacade(element);
|
||||
@@ -137,7 +144,31 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return facade.parseTypeAnnotation(typeString, anchor);
|
||||
final PyType type = facade.parseTypeAnnotation(typeString, anchor);
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
return getNominalType(anchor, typeString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts literal into type, e.g. -1 -> int, 'fro' -> str
|
||||
*/
|
||||
@Nullable
|
||||
private static PyType getNominalType(@NotNull PsiElement anchor, @NotNull String typeString) {
|
||||
final PyExpressionCodeFragmentImpl codeFragment = new PyExpressionCodeFragmentImpl(anchor.getProject(), "dummy.py", typeString, false);
|
||||
final PsiElement element = codeFragment.getFirstChild();
|
||||
if (element instanceof PyExpressionStatement) {
|
||||
final PyExpression expression = ((PyExpressionStatement)element).getExpression();
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(anchor);
|
||||
if (expression instanceof PyStringLiteralExpression) {
|
||||
return builtinCache.getStrType();
|
||||
}
|
||||
if (expression instanceof PyNumericLiteralExpression) {
|
||||
return builtinCache.getIntType();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -154,7 +185,7 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PyType getParameterType(@NotNull PyFunction function, @NotNull String parameterName) {
|
||||
private static PyType getParameterType(@NotNull PyFunction function, @NotNull String parameterName) {
|
||||
final NumPyDocString docString = NumPyDocString.forFunction(function, function);
|
||||
if (docString != null) {
|
||||
NumPyDocStringParameter parameter = docString.getNamedParameter(parameterName);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PyExceptionBreakpointProperties extends ExceptionBreakpointProperti
|
||||
public PyExceptionBreakpointProperties(@NotNull final String exception) {
|
||||
myException = exception;
|
||||
myNotifyOnTerminate = true;
|
||||
myIgnoreLibraries = true;
|
||||
myIgnoreLibraries = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,11 +34,9 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyStdlibUtil;
|
||||
import com.jetbrains.python.packaging.*;
|
||||
import com.jetbrains.python.packaging.ui.PyChooseRequirementsDialog;
|
||||
@@ -362,6 +360,63 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
public static class InstallAndImportQuickFix implements LocalQuickFix {
|
||||
|
||||
private final Sdk mySdk;
|
||||
private final Module myModule;
|
||||
private String myPackageName;
|
||||
@Nullable private final String myAsName;
|
||||
@NotNull private final SmartPsiElementPointer<PyElement> myNode;
|
||||
|
||||
public InstallAndImportQuickFix(@NotNull final String packageName,
|
||||
@Nullable final String asName,
|
||||
@NotNull final PyElement node) {
|
||||
myPackageName = packageName;
|
||||
myAsName = asName;
|
||||
myNode = SmartPointerManager.getInstance(node.getProject()).createSmartPsiElementPointer(node, node.getContainingFile());
|
||||
myModule = ModuleUtilCore.findModuleForPsiElement(node);
|
||||
mySdk = PythonSdkType.findPythonSdk(myModule);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "Install and import package " + myPackageName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return "Install and import package " + myPackageName;
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
|
||||
final PyPackageManagerUI ui = new PyPackageManagerUI(project, mySdk, new UIListener(myModule) {
|
||||
@Override
|
||||
public void finished(List<ExecutionException> exceptions) {
|
||||
super.finished(exceptions);
|
||||
if (exceptions.isEmpty()) {
|
||||
|
||||
final PyElement element = myNode.getElement();
|
||||
if (element == null) return;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AddImportHelper.addImportStatement(element.getContainingFile(), myPackageName, myAsName,
|
||||
AddImportHelper.ImportPriority.THIRD_PARTY, element);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, "Add import", "Add import");
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.install(Collections.singletonList(new PyRequirement(myPackageName)), Collections.<String>emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class UIListener implements PyPackageManagerUI.Listener {
|
||||
private final Module myModule;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
@@ -91,7 +92,7 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
if (!LOWERCASE_REGEX.matcher(name).matches() && !name.startsWith("_")) {
|
||||
registerProblem(expression, "Variable in function should be lowercase", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(expression, "Variable in function should be lowercase");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,10 +102,17 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
final String name = node.getName();
|
||||
if (name == null) return;
|
||||
if (!LOWERCASE_REGEX.matcher(name).matches()) {
|
||||
registerProblem(node, "Argument name should be lowercase", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(node, "Argument name should be lowercase");
|
||||
}
|
||||
}
|
||||
|
||||
private void registerAndAddRenameQuickFix(@Nullable final PsiElement node, @NotNull final String name) {
|
||||
if (getHolder() != null && getHolder().isOnTheFly())
|
||||
registerProblem(node, name, new PyRenameElementQuickFix());
|
||||
else
|
||||
registerProblem(node, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyFunction(PyFunction function) {
|
||||
final PyClass containingClass = function.getContainingClass();
|
||||
@@ -117,7 +125,10 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
if (!LOWERCASE_REGEX.matcher(name).matches()) {
|
||||
final ASTNode nameNode = function.getNameNode();
|
||||
if (nameNode != null) {
|
||||
final List<LocalQuickFix> quickFixes = Lists.<LocalQuickFix>newArrayList(new PyRenameElementQuickFix());
|
||||
final List<LocalQuickFix> quickFixes = Lists.newArrayList();
|
||||
if (getHolder() != null && getHolder().isOnTheFly())
|
||||
quickFixes.add(new PyRenameElementQuickFix());
|
||||
|
||||
if (containingClass != null) {
|
||||
quickFixes.add(new IgnoreBaseClassQuickFix(containingClass, myTypeEvalContext));
|
||||
}
|
||||
@@ -150,7 +161,7 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
if (!MIXEDCASE_REGEX.matcher(name).matches()) {
|
||||
final ASTNode nameNode = node.getNameNode();
|
||||
if (nameNode != null) {
|
||||
registerProblem(nameNode.getPsi(), "Class names should use CamelCase convention", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(nameNode.getPsi(), "Class names should use CamelCase convention");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,19 +176,19 @@ public class PyPep8NamingInspection extends PyInspection {
|
||||
if (asName == null || name == null) return;
|
||||
if (UPPERCASE_REGEX.matcher(name).matches()) {
|
||||
if (!UPPERCASE_REGEX.matcher(asName).matches()) {
|
||||
registerProblem(node.getAsNameElement(), "Constant variable imported as non constant", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(node.getAsNameElement(), "Constant variable imported as non constant");
|
||||
}
|
||||
}
|
||||
else if (LOWERCASE_REGEX.matcher(name).matches()) {
|
||||
if (!LOWERCASE_REGEX.matcher(asName).matches()) {
|
||||
registerProblem(node.getAsNameElement(), "Lowercase variable imported as non lowercase", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(node.getAsNameElement(), "Lowercase variable imported as non lowercase");
|
||||
}
|
||||
}
|
||||
else if (LOWERCASE_REGEX.matcher(asName).matches()) {
|
||||
registerProblem(node.getAsNameElement(), "CamelCase variable imported as lowercase", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(node.getAsNameElement(), "CamelCase variable imported as lowercase");
|
||||
}
|
||||
else if (UPPERCASE_REGEX.matcher(asName).matches()) {
|
||||
registerProblem(node.getAsNameElement(), "CamelCase variable imported as constant", new PyRenameElementQuickFix());
|
||||
registerAndAddRenameQuickFix(node.getAsNameElement(), "CamelCase variable imported as constant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -13,12 +13,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python;
|
||||
package com.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.quickFixes;
|
||||
package com.jetbrains.python.inspections.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.jetbrains.python.inspections.unresolvedReference;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PyPackageAliasesProvider {
|
||||
private PyPackageAliasesProvider() {
|
||||
}
|
||||
|
||||
public static final Map<String, String> commonAliases = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
commonAliases.put("np", "numpy");
|
||||
commonAliases.put("pl", "pylab");
|
||||
commonAliases.put("p", "pylab");
|
||||
commonAliases.put("sp", "scipy");
|
||||
commonAliases.put("pd", "pandas");
|
||||
commonAliases.put("sym", "sympy");
|
||||
commonAliases.put("sm", "statmodels");
|
||||
commonAliases.put("nx", "networkx");
|
||||
commonAliases.put("sk", "sklearn");
|
||||
|
||||
commonAliases.put("plt", "matplotlib.pyplot");
|
||||
commonAliases.put("mpimg", "matplotlib.image");
|
||||
commonAliases.put("mimg", "matplotlib.image");
|
||||
}
|
||||
}
|
||||
+27
-12
@@ -68,6 +68,7 @@ import com.jetbrains.python.psi.types.*;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import com.jetbrains.python.sdk.skeletons.PySkeletonRefresher;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -302,12 +303,10 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
if (element instanceof PyReferenceOwner) {
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext);
|
||||
final PsiPolyVariantReference reference = ((PyReferenceOwner)element).getReference(resolveContext);
|
||||
if (reference != null) {
|
||||
final ResolveResult[] resolveResults = reference.multiResolve(false);
|
||||
for (ResolveResult resolveResult : resolveResults) {
|
||||
if (resolveResult instanceof ImportedResolveResult) {
|
||||
myUsedImports.addAll(((ImportedResolveResult)resolveResult).getNameDefiners());
|
||||
}
|
||||
final ResolveResult[] resolveResults = reference.multiResolve(false);
|
||||
for (ResolveResult resolveResult : resolveResults) {
|
||||
if (resolveResult instanceof ImportedResolveResult) {
|
||||
myUsedImports.addAll(((ImportedResolveResult)resolveResult).getNameDefiners());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -571,11 +570,9 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
hl_type = ProblemHighlightType.LIKE_UNKNOWN_SYMBOL;
|
||||
}
|
||||
|
||||
if (element != null) {
|
||||
PyImportStatementBase importStatementBase = PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class);
|
||||
if ((importStatementBase != null) && GenerateBinaryStubsFix.isApplicable(importStatementBase)) {
|
||||
actions.addAll(GenerateBinaryStubsFix.generateFixes(importStatementBase));
|
||||
}
|
||||
PyImportStatementBase importStatementBase = PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class);
|
||||
if ((importStatementBase != null) && GenerateBinaryStubsFix.isApplicable(importStatementBase)) {
|
||||
actions.addAll(GenerateBinaryStubsFix.generateFixes(importStatementBase));
|
||||
}
|
||||
if (qualifiedNames.size() == 1) {
|
||||
final QualifiedName qualifiedName = qualifiedNames.get(0);
|
||||
@@ -873,6 +870,24 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
actions.add(importFix.forLocalImport());
|
||||
}
|
||||
}
|
||||
else {
|
||||
final String refName = (node instanceof PyQualifiedExpression) ? ((PyQualifiedExpression)node).getReferencedName() : node.getText();
|
||||
if (refName == null) return;
|
||||
final QualifiedName qname = QualifiedName.fromDottedString(refName);
|
||||
final List<String> components = qname.getComponents();
|
||||
if (!components.isEmpty()) {
|
||||
final String packageName = components.get(0);
|
||||
if (PyPIPackageUtil.INSTANCE.isInPyPI(packageName)) {
|
||||
actions.add(new PyPackageRequirementsInspection.InstallAndImportQuickFix(packageName, packageName, node));
|
||||
}
|
||||
else {
|
||||
final String packageAlias = PyPackageAliasesProvider.commonAliases.get(packageName);
|
||||
if (packageAlias != null && PyPIPackageUtil.INSTANCE.isInPyPI(packageName)) {
|
||||
actions.add(new PyPackageRequirementsInspection.InstallAndImportQuickFix(packageAlias, packageName, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean suppressHintForAutoImport(PyElement node, AutoImportQuickFix importFix) {
|
||||
@@ -891,7 +906,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addCreateClassFix(String refText, PsiElement element, List<LocalQuickFix> actions) {
|
||||
private void addCreateClassFix(@NonNls String refText, PsiElement element, List<LocalQuickFix> actions) {
|
||||
if (refText.length() > 2 && Character.isUpperCase(refText.charAt(0)) && !refText.toUpperCase().equals(refText) &&
|
||||
PsiTreeUtil.getParentOfType(element, PyImportStatementBase.class) == null) {
|
||||
PsiElement anchor = element;
|
||||
|
||||
@@ -56,7 +56,7 @@ import com.jetbrains.python.codeInsight.imports.OptimizeImportsQuickFix;
|
||||
import com.jetbrains.python.formatter.PyCodeStyleSettings;
|
||||
import com.jetbrains.python.inspections.PyPep8Inspection;
|
||||
import com.jetbrains.python.inspections.quickfix.ReformatFix;
|
||||
import com.jetbrains.python.quickFixes.RemoveTrailingBlankLinesFix;
|
||||
import com.jetbrains.python.inspections.quickfix.RemoveTrailingBlankLinesFix;
|
||||
import com.jetbrains.python.sdk.PreferredSdkComparator;
|
||||
import com.jetbrains.python.sdk.PySdkUtil;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user