From 8604f723da322d6375c358afa9c89863ce3e9efb Mon Sep 17 00:00:00 2001 From: "Matt Cholick (Rally laptop)" Date: Sun, 28 Oct 2012 19:53:52 -0700 Subject: [PATCH] initial checkin --- .gitignore | 7 +++ LICENSE.txt | 26 ++++++++ META-INF/plugin.xml | 28 +++++++++ README.md | 3 + .../highlight/SpockHighlightVisitor.java | 50 ++++++++++++++++ .../SpockLabelHighlightInfoTypes.java | 13 ++++ .../highlight/SpockPsiElementVisitor.java | 52 ++++++++++++++++ .../highlight/SpockPsiElementVisitorTest.java | 59 +++++++++++++++++++ 8 files changed, 238 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 META-INF/plugin.xml create mode 100644 README.md create mode 100644 src/main/com/cholick/idea/spock/highlight/SpockHighlightVisitor.java create mode 100644 src/main/com/cholick/idea/spock/highlight/SpockLabelHighlightInfoTypes.java create mode 100644 src/main/com/cholick/idea/spock/highlight/SpockPsiElementVisitor.java create mode 100644 src/test/com/cholick/idea/spock/highlight/SpockPsiElementVisitorTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bf2b96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +**.DS_Store +**~ + +.idea +*.iml + +out diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..04750fa --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2012, Matt Cholick +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml new file mode 100644 index 0000000..b9ebefb --- /dev/null +++ b/META-INF/plugin.xml @@ -0,0 +1,28 @@ + + Spock Enhancements + + Adds syntax highlighting to Spock labels. + + 0.1-alpha + Matt Cholick + + org.intellij.groovy + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..85bc642 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Spock Enhancements is a plugin for IntelliJ IDEA that improves integration with the Spock specification framework (http://code.google.com/p/spock/) + +This is very much alpha at the moment. diff --git a/src/main/com/cholick/idea/spock/highlight/SpockHighlightVisitor.java b/src/main/com/cholick/idea/spock/highlight/SpockHighlightVisitor.java new file mode 100644 index 0000000..21055b9 --- /dev/null +++ b/src/main/com/cholick/idea/spock/highlight/SpockHighlightVisitor.java @@ -0,0 +1,50 @@ +package com.cholick.idea.spock.highlight; + +import com.intellij.codeInsight.daemon.impl.HighlightVisitor; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +public class SpockHighlightVisitor implements HighlightVisitor { + + private SpockPsiElementVisitor spockPsiElementVisitor; + + public SpockHighlightVisitor() { + spockPsiElementVisitor = new SpockPsiElementVisitor(); + } + + @Override + public boolean suitableForFile(@NotNull PsiFile file) { + return file instanceof GroovyFile; + } + + @Override + public void visit(@NotNull PsiElement element) { + element.accept(spockPsiElementVisitor); + } + + @Override + public boolean analyze(@NotNull PsiFile file, boolean updateWholeFile, @NotNull HighlightInfoHolder holder, @NotNull Runnable action) { + spockPsiElementVisitor.setHighlightInfoHolder(holder); + try { + action.run(); + } finally { + spockPsiElementVisitor.clearHighlightInfoHolder(); + } + return true; + } + + @NotNull + @Override + public HighlightVisitor clone() { + return new SpockHighlightVisitor(); + } + + @Override + public int order() { + return 0; + } + +} diff --git a/src/main/com/cholick/idea/spock/highlight/SpockLabelHighlightInfoTypes.java b/src/main/com/cholick/idea/spock/highlight/SpockLabelHighlightInfoTypes.java new file mode 100644 index 0000000..8b7817b --- /dev/null +++ b/src/main/com/cholick/idea/spock/highlight/SpockLabelHighlightInfoTypes.java @@ -0,0 +1,13 @@ +package com.cholick.idea.spock.highlight; + +import com.intellij.codeInsight.daemon.impl.HighlightInfoType; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.editor.colors.TextAttributesKey; + +public class SpockLabelHighlightInfoTypes { + + private static final TextAttributesKey SPOCK_LABELS = TextAttributesKey.createTextAttributesKey("SPOCK_LABELS"); + + public static final HighlightInfoType SPOCK_LABEL = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, SPOCK_LABELS); + +} diff --git a/src/main/com/cholick/idea/spock/highlight/SpockPsiElementVisitor.java b/src/main/com/cholick/idea/spock/highlight/SpockPsiElementVisitor.java new file mode 100644 index 0000000..3f2dc5b --- /dev/null +++ b/src/main/com/cholick/idea/spock/highlight/SpockPsiElementVisitor.java @@ -0,0 +1,52 @@ +package com.cholick.idea.spock.highlight; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.editor.markup.EffectType; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel; + +import java.awt.Color; +import java.awt.Font; +import java.util.Arrays; +import java.util.List; + +public class SpockPsiElementVisitor extends PsiElementVisitor { + + private static final List LABELS = Arrays.asList("given", "setup", "when", "then", "and", "expect"); + + private HighlightInfoHolder highlightInfoHolder; + + @Override + public void visitElement(PsiElement element) { + if (!highlightInfoHolder.hasErrorResults()) { + if (element instanceof GrLabel && LABELS.contains(element.getText())) { + highlightInfoHolder.add(createHighlightInfo(element)); + } + } + } + + private static HighlightInfo createHighlightInfo(@NotNull PsiElement element) { + TextRange range = element.getTextRange(); + int start = range.getStartOffset(); + int end = range.getEndOffset(); + + TextAttributes textAttributes = new TextAttributes(Color.BLUE, null, null, EffectType.BOXED, Font.BOLD); + return new HighlightInfo(textAttributes, SpockLabelHighlightInfoTypes.SPOCK_LABEL, start, end, null, null, HighlightSeverity.INFORMATION, false, null, false); + } + + + public void clearHighlightInfoHolder() { + this.highlightInfoHolder = null; + } + + public void setHighlightInfoHolder(HighlightInfoHolder highlightInfoHolder) { + this.highlightInfoHolder = highlightInfoHolder; + } + +} diff --git a/src/test/com/cholick/idea/spock/highlight/SpockPsiElementVisitorTest.java b/src/test/com/cholick/idea/spock/highlight/SpockPsiElementVisitorTest.java new file mode 100644 index 0000000..d233e4f --- /dev/null +++ b/src/test/com/cholick/idea/spock/highlight/SpockPsiElementVisitorTest.java @@ -0,0 +1,59 @@ +package com.cholick.idea.spock.highlight; + +import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder; +import com.intellij.mock.MockProjectEx; +import com.intellij.mock.MockPsiElement; +import com.intellij.mock.MockPsiFile; +import com.intellij.mock.MockPsiManager; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.DummyHolderElement; +import com.intellij.testFramework.UsefulTestCase; +import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrLabelImpl; + +public class SpockPsiElementVisitorTest extends UsefulTestCase { + + public void setUp() throws Exception { + super.setUp(); + Extensions.registerAreaClass("IDEA_PROJECT", null); + } + + public void testVisitNonSpockElement() { + HighlightInfoHolder highlightInfoHolder = new HighlightInfoHolder(getMockFile()); + SpockPsiElementVisitor elementVisitor = new SpockPsiElementVisitor(); + elementVisitor.setHighlightInfoHolder(highlightInfoHolder); + + elementVisitor.visitElement(new MockPsiElement(myTestRootDisposable)); + + assertEquals(0, highlightInfoHolder.size()); + } + + public void testVisitNonSpockLabel() { + HighlightInfoHolder highlightInfoHolder = new HighlightInfoHolder(getMockFile()); + SpockPsiElementVisitor elementVisitor = new SpockPsiElementVisitor(); + elementVisitor.setHighlightInfoHolder(highlightInfoHolder); + + elementVisitor.visitElement(new GrLabelImpl(new DummyHolderElement("uncle_bob"))); + + assertEquals(0, highlightInfoHolder.size()); + } + + public void testVisitSpockElement() { + String label = "given"; + + HighlightInfoHolder highlightInfoHolder = new HighlightInfoHolder(getMockFile()); + SpockPsiElementVisitor elementVisitor = new SpockPsiElementVisitor(); + elementVisitor.setHighlightInfoHolder(highlightInfoHolder); + + elementVisitor.visitElement(new GrLabelImpl(new DummyHolderElement(label))); + + assertEquals(1, highlightInfoHolder.size()); + assertEquals(0, highlightInfoHolder.get(0).getStartOffset()); + assertEquals(label.length(), highlightInfoHolder.get(0).getEndOffset()); + } + + private PsiFile getMockFile() { + return new MockPsiFile(new MockPsiManager(new MockProjectEx(myTestRootDisposable))); + } + +}