Skip to content

Commit

Permalink
Merge pull request #1 from AbnerZheng/master
Browse files Browse the repository at this point in the history
Add folding feature and initial test framework.
  • Loading branch information
tgrospic authored Jan 27, 2018
2 parents 3ac807e + dae7717 commit 0fdf446
Show file tree
Hide file tree
Showing 18 changed files with 4,222 additions and 9 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
out/
.idea/workspace.xml
gen/
*.java~
/*.jar
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/uiDesigner.xml
.idea/misc.xml

7 changes: 7 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ Any feedback, suggestions, bugs, testing, pull-requests, issues are very welcome
- create new Plugin Run configuration with default setup
- run/debug in a separate editor

### Test

Intellij has provide some test frameworks.These framework do simplified verifying work. For more detail you can read [IntelliJ Platform SDK DevGuide
][idea-test-guide]

#### How to use

Just as using JUnit, there is a 'run' button on the left of the class or test case. You can click this button to run or debug. But there will be error after you run the test case, reporting that can not find the file. Now, you should config the run configuration, and set the vm option as follows:

```
-ea -Xbootclasspath/p:../out/classes/production/boot -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m -Didea.system.path=../test-system -Didea.home.path=./ -Didea.config.path=../test-config -Didea.test.group=ALL_EXCLUDE_DEFINED
```

Then rerun the test case, and you'll find it works.

### Deployment

- generate _jar_ file through the project root context menu [Prepare Plugin Module ... For Deployment][idea-deploy]
Expand Down Expand Up @@ -76,6 +91,7 @@ Any feedback, suggestions, bugs, testing, pull-requests, issues are very welcome
[idea-completion]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/completion_contributor.html
[idea-reference]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/reference_contributor.html
[idea-plugin-actions]: https://www.jetbrains.org/intellij/sdk/docs/basics/action_system.html
[idea-test-guide]: https://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins.html

[beta-badge]: https://cdn.rawgit.com/tgrospic/rholang-idea/master/docs/beta-0.0.3.svg
[license]: https://github.com/tgrospic/rholang-idea/blob/master/LICENSE
2 changes: 2 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<lang.parserDefinition language="Rholang" implementationClass="coop.rchain.lang.RhoParserDefinition"/>
<lang.syntaxHighlighterFactory language="Rholang" implementationClass="coop.rchain.lang.RhoSyntaxHighlighterFactory"/>
<lang.commenter language="Rholang" implementationClass="coop.rchain.lang.RhoCommenter"/>
<lang.foldingBuilder language="Rholang" implementationClass="coop.rchain.lang.folding.RholangFoldingBuilder"/>

<colorSettingsPage implementation="coop.rchain.lang.RhoColorSettingsPage"/>
<annotator language="Rholang" implementationClass="coop.rchain.lang.RhoHighlightingAnnotator"/>
</extensions>
Expand Down
11 changes: 11 additions & 0 deletions rholang-idea.iml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/testData" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="gen" level="project" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$MODULE_DIR$/bin/jflex-1.6.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
16 changes: 9 additions & 7 deletions src/coop/rchain/lang/Rho.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@
// Top level contract declaration

Contract ::= Proc
Contract_ ::= CONTRACT ContractName "(" [CPattern] ")" "=" "{" Proc "}"
Contract_ ::= CONTRACT ContractName "(" [CPattern] ")" "=" ProcBlock
| CONTRACT ContractName "=" TypeTerm

ProcBlock ::= "{" [Proc] "}"

ContractName ::= ID_NAME {
implements = [ "coop.rchain.lang.psi.RhoNamedElement" ]
mixin = "coop.rchain.lang.psi.RhoNamedElementImpl"
Expand All @@ -107,13 +109,13 @@ private comment ::= (BLOCK_COMMENT|BLOCK_DOC_COMMENT|LINE_COMMENT|LINE_DOC_COMME
Proc4 ::= NIL | Value
Proc3 ::= ChanRefSymbol Chan ["(" [Proc] ")"]
Proc2 ::= Chan "!" "(" [Proc] ")"
Proc1 ::= SUM "(" Bind "/:" Bind ")" "{" Proc "}"
| TOTAL "(" Bind ":\\" Bind ")" "{" Proc "}"
Proc1 ::= SUM "(" Bind "/:" Bind ")" ProcBlock
| TOTAL "(" Bind ":\\" Bind ")" ProcBlock
| FOR "(" [Bind] ")" "{" [Proc] "}"
| SELECT "{" [CBranch] "}"
| MATCH Proc WITH [PMBranch]
| MATCH Proc { [PMBranch] }
| NEW [VarPattern] IN "{" Proc "}"
| NEW [VarPattern] IN ProcBlock
| NEW [VarPattern] IN Proc
| LET ("(" CPattern ")" | CPattern) "=" Proc IN Proc
| ConstrName "(" [Proc] ")"
Expand All @@ -129,7 +131,7 @@ ChanRefSymbol ::= "*"|"#" {
}

// Experimental!
FnDef ::= DEF FnName "(" [CPattern] ")" "=" "{" Proc "}"
FnDef ::= DEF FnName "(" [CPattern] ")" "=" ProcBlock
| DEF FnName "=" TypeTerm

FnName ::= ID_NAME {
Expand All @@ -156,12 +158,12 @@ Bind_ ::= CPattern "<-" Chan IF Proc
Bind ::= Bind_ (";" Bind_)*

// Pattern match branches
PMBranch_ ::= PPattern "=>" "{" Proc "}"
PMBranch_ ::= PPattern "=>" ProcBlock
PMBranch ::= PMBranch_ PMBranch_*

// Choice branch
CBranch ::= CBranch_ CBranch_*
CBranch_ ::= CASE [Bind] "=>" "{" Proc "}"
CBranch_ ::= CASE [Bind] "=>" ProcBlock

QVal ::= TRUE
| FALSE
Expand Down
67 changes: 67 additions & 0 deletions src/coop/rchain/lang/folding/RholangFoldingBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package coop.rchain.lang.folding

import com.intellij.lang.ASTNode
import com.intellij.lang.folding.CustomFoldingBuilder
import com.intellij.lang.folding.FoldingBuilder
import com.intellij.lang.folding.FoldingDescriptor
import com.intellij.openapi.editor.Document
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.PsiTreeUtil
import coop.rchain.lang.psi.RhoFile
import coop.rchain.lang.psi.RhoProc
import coop.rchain.lang.psi.RhoTypes
import coop.rchain.lang.psi.impl.RhoProcBlockImpl

import java.util.ArrayList

class RholangFoldingBuilder : FoldingBuilder, DumbAware {

override fun buildFoldRegions(node: ASTNode, document: Document): Array<FoldingDescriptor> {
val descriptors = ArrayList<FoldingDescriptor>()
appendDescriptors(node.psi, descriptors, document)

return descriptors.toTypedArray()
}

private fun appendDescriptors(psi: PsiElement, descriptors: MutableList<FoldingDescriptor>, document: Document) {
if (isSingleLine(psi, document)) { // don't fold when text is single line
return
}

val elementType = psi.node.elementType

if (elementType === RhoTypes.BLOCK_DOC_COMMENT) {
val blockDocComment = psi.node
val range = TextRange(blockDocComment.textRange.startOffset + 3, blockDocComment.textRange.endOffset - 2)
descriptors.add(FoldingDescriptor(blockDocComment, range))
} else if (elementType === RhoTypes.PROC_BLOCK) {
val textRange = psi.node.textRange
val textRange1 = TextRange(textRange.startOffset + 1, textRange.endOffset - 1)
descriptors.add(FoldingDescriptor(psi.node, textRange1))
}

var child: PsiElement? = psi.firstChild
while (child != null) {
appendDescriptors(child, descriptors, document)
child = child.nextSibling
}
}


private fun isSingleLine(element: PsiElement, document: Document): Boolean {
val textRange = element.textRange
return document.getLineNumber(textRange.startOffset) == document.getLineNumber(textRange.endOffset)
}

override fun getPlaceholderText(node: ASTNode): String? {
return "..."
}

override fun isCollapsedByDefault(node: ASTNode): Boolean {
return false
}
}
8 changes: 8 additions & 0 deletions test/coop/rchain/RholangTestUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package coop.rchain

import com.intellij.openapi.application.PathManager

object RholangTestUtil {
val baseTestDataPath: String
get() = PathManager.getHomePath() + "/testData"
}
20 changes: 20 additions & 0 deletions test/coop/rchain/ide/folding/RholangCodeInsightTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package coop.rchain.ide.folding

import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import coop.rchain.RholangTestUtil.baseTestDataPath


class RholangCodeInsightTest : LightCodeInsightFixtureTestCase() {
override fun getTestDataPath(): String {
return baseTestDataPath
}

fun testFolding() {
doTestFolding("blockDocComment")
doTestFolding("procedure")
}

private fun doTestFolding(testName: String) {
myFixture.testFolding("$testDataPath/ide/folding/$testName.rho")
}
}
24 changes: 24 additions & 0 deletions test/coop/rchain/lang/lexer/RholangLexTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package coop.rchain.lang.lexer

import com.intellij.lexer.Lexer
import com.intellij.openapi.application.PathManager
import com.intellij.testFramework.LexerTestCase
import coop.rchain.RholangTestUtil
import coop.rchain.lang.RhoLexerAdapter

import java.nio.file.Paths

class RholangLexTest : LexerTestCase() {

override fun createLexer(): Lexer {
return RhoLexerAdapter()
}

override fun getDirPath(): String {
return Paths.get(RholangTestUtil.baseTestDataPath, "lexer").toString().substring(PathManager.getHomePath().length)
}

fun testToken() {
doFileTest("rho")
}
}
17 changes: 17 additions & 0 deletions test/coop/rchain/lang/parser/RholangParserTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package coop.rchain.lang.parser

import com.intellij.testFramework.ParsingTestCase
import coop.rchain.RholangTestUtil
import coop.rchain.lang.RhoParserDefinition
import java.nio.file.Paths

class RholangParserTest : ParsingTestCase("", "rho", RhoParserDefinition()) {

override fun getTestDataPath(): String {
return Paths.get(RholangTestUtil.baseTestDataPath, "parser").toString()
}

fun testtoken() {
doTest(true)
}
}
4 changes: 4 additions & 0 deletions testData/ide/folding/blockDocComment.rho
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**<fold text='...'>
* Test
</fold>*/

7 changes: 7 additions & 0 deletions testData/ide/folding/procedure.rho
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
new time_contract in {
contract time_contract(stream) = {
log-time(stream)
} |
time_contract!(ostream-new("test.txt")) |
time_contract!(ostream-new("test2.txt"))
}
Loading

0 comments on commit 0fdf446

Please sign in to comment.