From a8e5ad91c7599028dc9977e02bbc750a47b09f41 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 27 Jul 2010 14:44:16 +0400 Subject: [PATCH 01/10] vfs zip exceptions fixed --- .../history/core/ChangeListStorageImpl.java | 2 +- .../util/io/storage/AbstractStorage.java | 84 +++++++++---------- .../util/io/storage/RefCountingStorage.java | 50 ++++++----- 3 files changed, 72 insertions(+), 64 deletions(-) diff --git a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java index 10de5a3fd2a4..ec49a27bbd64 100644 --- a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java +++ b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java @@ -102,8 +102,8 @@ public class ChangeListStorageImpl implements ChangeListStorage { } private ChangeSetBlock doReadBlock(int id) { - DataInputStream in = myStorage.readStream(id); try { + DataInputStream in = myStorage.readStream(id); try { int size = in.readInt(); List changes = new ArrayList(size); diff --git a/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java b/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java index 7192537ef2cc..cd47b1a0c146 100644 --- a/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java +++ b/platform/util/src/com/intellij/util/io/storage/AbstractStorage.java @@ -200,7 +200,47 @@ public abstract class AbstractStorage implements Disposable, Forceable { } } - private void appendBytes(int record, byte[] bytes) { + private static int calcCapacity(int requiredLength) { + return Math.max(64, nearestPowerOfTwo(requiredLength * 3 / 2)); + } + + private static int nearestPowerOfTwo(int n) { + int power = 1; + while (n != 0) { + power *= 2; + n /= 2; + } + return power; + } + + public StorageDataOutput writeStream(final int record) { + return new StorageDataOutput(this, record); + } + + public AppenderStream appendStream(int record) { + return new AppenderStream(record); + } + + public DataInputStream readStream(int record) throws IOException { + final byte[] bytes = readBytes(record); + return new DataInputStream(new ByteArrayInputStream(bytes)); + } + + protected byte[] readBytes(int record) throws IOException { + synchronized (myLock) { + final int length = myRecordsTable.getSize(record); + if (length == 0) return ArrayUtil.EMPTY_BYTE_ARRAY; + assert length > 0; + + final long address = myRecordsTable.getAddress(record); + byte[] result = new byte[length]; + myDataTable.readBytes(address, result); + + return result; + } + } + + protected void appendBytes(int record, byte[] bytes) throws IOException { int delta = bytes.length; if (delta == 0) return; @@ -227,7 +267,7 @@ public abstract class AbstractStorage implements Disposable, Forceable { } } - public void writeBytes(int record, byte[] bytes) { + protected void writeBytes(int record, byte[] bytes) throws IOException { synchronized (myLock) { final int requiredLength = bytes.length; final int currentCapacity = myRecordsTable.getCapacity(record); @@ -257,46 +297,6 @@ public abstract class AbstractStorage implements Disposable, Forceable { } } - private static int calcCapacity(int requiredLength) { - return Math.max(64, nearestPowerOfTwo(requiredLength * 3 / 2)); - } - - private static int nearestPowerOfTwo(int n) { - int power = 1; - while (n != 0) { - power *= 2; - n /= 2; - } - return power; - } - - public StorageDataOutput writeStream(final int record) { - return new StorageDataOutput(this, record); - } - - public AppenderStream appendStream(int record) { - return new AppenderStream(record); - } - - public DataInputStream readStream(int record) { - final byte[] bytes = readBytes(record); - return new DataInputStream(new ByteArrayInputStream(bytes)); - } - - byte[] readBytes(int record) { - synchronized (myLock) { - final int length = myRecordsTable.getSize(record); - if (length == 0) return ArrayUtil.EMPTY_BYTE_ARRAY; - assert length > 0; - - final long address = myRecordsTable.getAddress(record); - byte[] result = new byte[length]; - myDataTable.readBytes(address, result); - - return result; - } - } - protected void doDeleteRecord(int record) throws IOException { myDataTable.reclaimSpace(myRecordsTable.getSize(record)); myRecordsTable.deleteRecord(record); diff --git a/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java b/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java index 8851d17f8130..68fd54cb9e50 100644 --- a/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java +++ b/platform/util/src/com/intellij/util/io/storage/RefCountingStorage.java @@ -19,10 +19,14 @@ */ package com.intellij.util.io.storage; +import com.intellij.openapi.util.io.StreamUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.io.PagePool; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; @@ -31,32 +35,36 @@ public class RefCountingStorage extends AbstractStorage { super(path); } - public RefCountingStorage(String path, PagePool pool) throws IOException { - super(path, pool); + @Override + protected byte[] readBytes(int record) throws IOException { + byte[] result = super.readBytes(record); + InflaterInputStream in = new InflaterInputStream(new ByteArrayInputStream(result)); + try { + return StreamUtil.loadFromStream(in); + } + finally { + in.close(); + } } @Override - public StorageDataOutput writeStream(int record) { - final ByteArrayOutputStream stream = new ByteArrayOutputStream(); - return new StorageDataOutput(this, record, new DeflaterOutputStream(stream)) { - @Override - protected ByteArrayOutputStream getByteStream() { - return stream; - } - }; - } - - @Override - public DataInputStream readStream(int record) { - final byte[] bytes = readBytes(record); - return new DataInputStream(new InflaterInputStream(new ByteArrayInputStream(bytes))); - } - - @Override - public AppenderStream appendStream(int record) { + protected void appendBytes(int record, byte[] bytes) throws IOException { throw new IncorrectOperationException("Appending is not supported"); } + @Override + protected void writeBytes(int record, byte[] bytes) throws IOException { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + DeflaterOutputStream out = new DeflaterOutputStream(s); + try { + out.write(bytes); + } + finally { + out.close(); + } + super.writeBytes(record, s.toByteArray()); + } + @Override protected AbstractRecordsTable createRecordsTable(PagePool pool, File recordsFile) throws IOException { return new RefCountingRecordsTable(recordsFile, pool); From ab39c94d8e8525cdaea67966620544e27018ae6d Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 28 Jul 2010 14:03:36 +0400 Subject: [PATCH 02/10] Maven: npe in psi property resolver --- .../idea/maven/dom/references/MavenPropertyPsiReference.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java index a8932a636b07..8f53098da26b 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPropertyPsiReference.java @@ -182,6 +182,7 @@ public class MavenPropertyPsiReference extends MavenPsiReference { result = new MavenDomProjectProcessorUtils.DomParentProjectFileProcessor(myProjectsManager) { protected PsiElement doProcessParent(VirtualFile parentFile) { MavenDomProjectModel parentProjectDom = MavenDomUtil.getMavenDomProjectModel(myProject, parentFile); + if (parentProjectDom == null) return null; return resolveModelProperty(parentProjectDom, path, recursionGuard); } }.process(projectDom); From 3958cf9b27be49e10097be8e5013ae83ace10b45 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 28 Jul 2010 15:31:09 +0400 Subject: [PATCH 03/10] Maven: logging --- .../org/jetbrains/idea/maven/project/MavenProjectsManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java index 6612d595c6cc..8c87b9318323 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java @@ -224,7 +224,7 @@ public class MavenProjectsManager extends SimpleProjectComponent myProjectsTree.save(getProjectsTreeFile()); } catch (IOException e) { - MavenLog.LOG.error(e); + MavenLog.LOG.warn(e); } } } From 642950b5110a120202d49b6b2e135d8e8fee7078 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 28 Jul 2010 15:35:15 +0400 Subject: [PATCH 04/10] Maven: invalid file access fix --- .../jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java index 4493fb80522b..f965aa5cf0bc 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java @@ -125,6 +125,8 @@ public class MavenModuleBuilderHelper { // execute when current dialog is closed (e.g. Project Structure) MavenUtil.invokeLater(project, ModalityState.NON_MODAL, new Runnable() { public void run() { + if (!pom.isValid()) return; + EditorHelper.openInEditor(getPsiFile(project, pom)); if (myArchetype != null) generateFromArchetype(project, pom); } From 67ec9973efe53760d1a60c63539ef2a36a699823 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Wed, 28 Jul 2010 16:51:15 +0400 Subject: [PATCH 05/10] scroll pane: npe fix --- .../intellij/ui/components/JBScrollPane.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index 10dbfd4fed5d..e5e24128b218 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -58,16 +58,19 @@ public class JBScrollPane extends JScrollPane { @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { JViewport vp = getViewport(); - if (vp != null) { - Color bg = vp.getView().getBackground(); - if (bg != null) { - g.setColor(bg); - g.drawLine(0, 0, width - 1, 0); - g.drawLine(0, height - 1, width - 1, height - 1); - g.drawLine(0, 0, 0, height - 1); - g.drawLine(width - 1, 0, width - 1, height - 1); - } - } + if (vp == null) return; + + Component view = vp.getView(); + if (view == null) return; + + Color bg = view.getBackground(); + if (bg == null) return; + + g.setColor(bg); + g.drawLine(0, 0, width - 1, 0); + g.drawLine(0, height - 1, width - 1, height - 1); + g.drawLine(0, 0, 0, height - 1); + g.drawLine(width - 1, 0, width - 1, height - 1); } @Override From e66b430cd7b5357acc1b2af7e778e7c479225b51 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 28 Jul 2010 16:01:12 +0400 Subject: [PATCH 06/10] refactoring --- .../controlflow/ControlFlowUtil.java | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/controlflow/ControlFlowUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/controlflow/ControlFlowUtil.java index 7da42a52b808..1d05cdb39d80 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/controlflow/ControlFlowUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/controlflow/ControlFlowUtil.java @@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -28,16 +29,16 @@ import java.util.Arrays; * @author oleg */ public class ControlFlowUtil { - private static final Logger LOG = Logger.getInstance(ControlFlowUtil.class.getName()); + private static final Logger LOG = Logger.getInstance(ControlFlowUtil.class.getName()); private ControlFlowUtil() { } public static class Stack { + private final int myCapacity; private final int[] myValues; private int myIndex; - public Stack(final int capacity) { myCapacity = capacity; myValues = new int[myCapacity]; @@ -65,8 +66,8 @@ public class ControlFlowUtil { public String toString() { return "Stack(" + (myIndex + 1) + ") elements"; } - } + } public static int[] postOrder(Instruction[] flow) { final int length = flow.length; int[] result = new int[length]; @@ -108,6 +109,7 @@ public class ControlFlowUtil { } // Process control flow in depth first order + public static boolean process(final Instruction[] flow, final int start, final Processor processor){ final int length = flow.length; boolean[] visited = new boolean[length]; @@ -135,4 +137,35 @@ public class ControlFlowUtil { } return true; } + + + public static void iteratePrev(final int startInstruction, + @NotNull final Instruction[] instructions, + @NotNull final Function closure) { + final Stack stack = new Stack(instructions.length); + final boolean[] visited = new boolean[instructions.length]; + + stack.push(startInstruction); + while (!stack.isEmpty()) { + final int num = stack.pop(); + if (visited[num]){ + continue; + } + visited[num] = true; + final Instruction instr = instructions[num]; + final Operation nextOperation = closure.fun(instr); + if (nextOperation == Operation.CONTINUE) { + continue; + } else if (nextOperation == Operation.BREAK) { + break; + } + for (Instruction pred : instr.allPred()) { + stack.push(pred.num()); + } + } + } + + public static enum Operation { + CONTINUE, BREAK, NEXT; + } } \ No newline at end of file From 18d929efe5a1066d9663bcd8f99e15195a2df04c Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 28 Jul 2010 16:20:54 +0400 Subject: [PATCH 07/10] RUBY-6429 SASS: don't consider indentation in the commented lines while checking indentation --- .../IndentationAnnotatorVisitor.java | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/indentation/IndentationAnnotatorVisitor.java b/platform/lang-impl/src/com/intellij/indentation/IndentationAnnotatorVisitor.java index 937198ab81e8..facb47a68a3a 100644 --- a/platform/lang-impl/src/com/intellij/indentation/IndentationAnnotatorVisitor.java +++ b/platform/lang-impl/src/com/intellij/indentation/IndentationAnnotatorVisitor.java @@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @@ -15,13 +16,16 @@ public class IndentationAnnotatorVisitor extends PsiElementVisitor { protected final AnnotationHolder myHolder; private final IElementType myIndentTokenType; private final IElementType myEolTokenType; + private final TokenSet myCommentTypes; public IndentationAnnotatorVisitor(@NotNull final AnnotationHolder holder, final IElementType indentTokenType, - final IElementType eolTokenType) { + final IElementType eolTokenType, + final TokenSet commentTypes) { myHolder = holder; myIndentTokenType = indentTokenType; myEolTokenType = eolTokenType; + myCommentTypes = commentTypes; } @SuppressWarnings({"ConstantConditions"}) @@ -45,43 +49,46 @@ public class IndentationAnnotatorVisitor extends PsiElementVisitor { // Iterating over leafs while (leaf != null) { final IElementType leafType = leaf.getNode().getElementType(); - if (leafType == myIndentTokenType && nextLeaf!=null && nextLeaf.getNode().getElementType() != myEolTokenType){ - final String currentIndentText = leaf.getText(); - final IndentInfo currentIndent = getIndent(currentIndentText); - final int currentIndentLength = currentIndent.length; - // Check if spaces and tabs are mixed - if (currentIndentLength == -1){ - myHolder.createErrorAnnotation(leaf, "Indentation can't use both tabs and spaces"); - } - else - if (currentIndentLength > 0) { - // If we don't have indent info registered - if (indentInfo == null){ - indentInfo = currentIndent; - lastIndent = currentIndentLength; - } else { - final Boolean useTab = indentInfo.useTab; - final int indentInfoLength = indentInfo.length; - // If indent and current indent use different space and tabs - if (useTab && currentIndentText.contains(" ") || !useTab && currentIndentText.contains("\t")) { - final String message = useTab - ? "Inconsistent indentation: " + currentIndentLength + - " spaces were used for indentation, but the rest of the document was indented using " + - indentInfoLength + " tabs" - : "Inconsistent indentation: " + currentIndentLength + - " tabs were used for indentation, but the rest of the document was indented using " + - indentInfoLength + " spaces"; - myHolder.createErrorAnnotation(leaf, message); + if (leafType == myIndentTokenType && nextLeaf != null) { + final IElementType nextLeafType = nextLeaf.getNode().getElementType(); + if (nextLeafType != myEolTokenType && !myCommentTypes.contains(nextLeafType)){ + final String currentIndentText = leaf.getText(); + final IndentInfo currentIndent = getIndent(currentIndentText); + final int currentIndentLength = currentIndent.length; + // Check if spaces and tabs are mixed + if (currentIndentLength == -1){ + myHolder.createErrorAnnotation(leaf, "Indentation can't use both tabs and spaces"); + } + else + if (currentIndentLength > 0) { + // If we don't have indent info registered + if (indentInfo == null){ + indentInfo = currentIndent; + lastIndent = currentIndentLength; } else { - // Check indent length - final int delta = currentIndentLength - lastIndent; - if (currentIndentLength % indentInfoLength != 0 || delta > indentInfoLength) { - final String message = useTab - ? currentIndentLength + " tabs were used for indentation. Must be indented using " + indentInfoLength + " tabs" - : currentIndentLength + " spaces were used for indentation. Must be indented using " + indentInfoLength + " spaces"; + final Boolean useTab = indentInfo.useTab; + final int indentInfoLength = indentInfo.length; + // If indent and current indent use different space and tabs + if (useTab && currentIndentText.contains(" ") || !useTab && currentIndentText.contains("\t")) { + final String message = useTab + ? "Inconsistent indentation: " + currentIndentLength + + " spaces were used for indentation, but the rest of the document was indented using " + + indentInfoLength + " tabs" + : "Inconsistent indentation: " + currentIndentLength + + " tabs were used for indentation, but the rest of the document was indented using " + + indentInfoLength + " spaces"; myHolder.createErrorAnnotation(leaf, message); + } else { + // Check indent length + final int delta = currentIndentLength - lastIndent; + if (currentIndentLength % indentInfoLength != 0 || delta > indentInfoLength) { + final String message = useTab + ? currentIndentLength + " tabs were used for indentation. Must be indented using " + indentInfoLength + " tabs" + : currentIndentLength + " spaces were used for indentation. Must be indented using " + indentInfoLength + " spaces"; + myHolder.createErrorAnnotation(leaf, message); + } + lastIndent = currentIndentLength / indentInfoLength * indentInfoLength; } - lastIndent = currentIndentLength / indentInfoLength * indentInfoLength; } } } From 3adddf62b82ebeea028712eda64b918ab4b4db1f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 28 Jul 2010 18:42:58 +0400 Subject: [PATCH 08/10] same directory proximity weigher for use in non-IDEA IDEs --- .../util/proximity/SameDirectoryWeigher.java | 48 +++++++++++++++++++ .../src/META-INF/PlatformLangPlugin.xml | 2 + 2 files changed, 50 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/psi/util/proximity/SameDirectoryWeigher.java diff --git a/platform/lang-impl/src/com/intellij/psi/util/proximity/SameDirectoryWeigher.java b/platform/lang-impl/src/com/intellij/psi/util/proximity/SameDirectoryWeigher.java new file mode 100644 index 000000000000..13df01e65c5a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/util/proximity/SameDirectoryWeigher.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2010 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.psi.util.proximity; + +import com.intellij.openapi.util.NullableLazyKey; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.ProximityLocation; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.NullableFunction; +import org.jetbrains.annotations.NotNull; + +/** + * NOTE: This class is only registered in platform-based IDEs. In IDEA, SamePackageWeigher is used instead. + * + * @author yole + */ +public class SameDirectoryWeigher extends ProximityWeigher { + private static final NullableLazyKey + PLACE_DIRECTORY = NullableLazyKey.create("placeDirectory", new NullableFunction() { + @Override + public PsiDirectory fun(ProximityLocation location) { + return PsiTreeUtil.getParentOfType(location.getPosition(), PsiDirectory.class, false); + } + }); + + public Comparable weigh(@NotNull final PsiElement element, final ProximityLocation location) { + final PsiDirectory placeDirectory = PLACE_DIRECTORY.getValue(location); + if (placeDirectory == null) { + return false; + } + + return placeDirectory.equals(PsiTreeUtil.getParentOfType(element, PsiDirectory.class, false)); + } +} diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml index f8d8e74278dc..ec1066d133c7 100644 --- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml @@ -80,6 +80,8 @@ + From 0947ba5f5b847dedf7c0f0236d01665c9c312759 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Wed, 28 Jul 2010 20:07:28 +0400 Subject: [PATCH 09/10] obj-c quick doc --- .../documentation/DocumentationComponent.java | 12 +++-- .../documentation/DocumentationManager.java | 48 +++++++++++-------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java index af28c5a55eeb..6233d8a2872f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java @@ -22,6 +22,7 @@ import com.intellij.codeInsight.hint.HintManagerImpl; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.ide.actions.ExternalJavaDocAction; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.lang.documentation.ExternalDocumentationHandler; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.ui.popup.JBPopup; @@ -405,10 +406,13 @@ public class DocumentationComponent extends JPanel implements Disposable { if (myElement != null) { final PsiElement element = myElement.getElement(); final DocumentationProvider provider = DocumentationManager.getProviderFromElement(element); - final List urls = provider.getUrlFor(element, DocumentationManager.getOriginalElement(element)); - assert urls != null; - assert !urls.isEmpty(); - ExternalJavaDocAction.showExternalJavadoc(urls); + final PsiElement originalElement = DocumentationManager.getOriginalElement(element); + if (!(provider instanceof ExternalDocumentationHandler) || !((ExternalDocumentationHandler)provider).handleExternal(element, originalElement)) { + final List urls = provider.getUrlFor(element, originalElement); + assert urls != null; + assert !urls.isEmpty(); + ExternalJavaDocAction.showExternalJavadoc(urls); + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 0f6dcfa19449..0a5dabb5223e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -33,6 +33,7 @@ import com.intellij.lang.Language; import com.intellij.lang.LanguageDocumentation; import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.lang.documentation.ExternalDocumentationHandler; import com.intellij.lang.documentation.ExternalDocumentationProvider; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; @@ -816,38 +817,43 @@ public class DocumentationManager { } } else { + final DocumentationProvider provider = getProviderFromElement(psiElement); + if (!(provider instanceof ExternalDocumentationHandler) || + !((ExternalDocumentationHandler)provider).handleExternalLink(manager, url, psiElement)) { final String docUrl = url; - fetchDocInfo - (new DocumentationCollector() { - public String getDocumentation() throws Exception { - if (docUrl.startsWith(DOC_ELEMENT_PROTOCOL)) { - final List urls = ApplicationManager.getApplication().runReadAction( + fetchDocInfo + (new DocumentationCollector() { + public String getDocumentation() throws Exception { + if (docUrl.startsWith(DOC_ELEMENT_PROTOCOL)) { + final List urls = ApplicationManager.getApplication().runReadAction( new Computable>() { public List compute() { final DocumentationProvider provider = getProviderFromElement(psiElement); return provider.getUrlFor(psiElement, getOriginalElement(psiElement)); } } - ); - BrowserUtil.launchBrowser(urls != null && !urls.isEmpty() ? urls.get(0) : docUrl); - } else { - BrowserUtil.launchBrowser(docUrl); + ); + BrowserUtil.launchBrowser(urls != null && !urls.isEmpty() ? urls.get(0) : docUrl); + } + else { + BrowserUtil.launchBrowser(docUrl); + } + return ""; } - return ""; - } - public PsiElement getElement() { - //String loc = getElementLocator(docUrl); - // - //if (loc != null) { - // PsiElement context = component.getElement(); - // return JavaDocUtil.findReferenceTarget(context.getManager(), loc, context); - //} + public PsiElement getElement() { + //String loc = getElementLocator(docUrl); + // + //if (loc != null) { + // PsiElement context = component.getElement(); + // return JavaDocUtil.findReferenceTarget(context.getManager(), loc, context); + //} - return psiElement; - } - }, component); + return psiElement; + } + }, component); + } } component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); From 3a40b276dffe1f5bc0e629e26f2539ddb03f59e9 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Wed, 28 Jul 2010 20:12:33 +0400 Subject: [PATCH 10/10] ExternalDocumentationHandler --- .../ExternalDocumentationHandler.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationHandler.java diff --git a/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationHandler.java b/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationHandler.java new file mode 100644 index 000000000000..0584d7cff1cd --- /dev/null +++ b/platform/lang-api/src/com/intellij/lang/documentation/ExternalDocumentationHandler.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2010 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.lang.documentation; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; + +/** + * User: spLeaner + */ +public interface ExternalDocumentationHandler { + boolean handleExternal(PsiElement element, PsiElement originalElement); + boolean handleExternalLink(PsiManager psiManager, String link, PsiElement context); +}