Skip to content

Commit

Permalink
parser: ignore #_-commented forms in maps and tagged literals
Browse files Browse the repository at this point in the history
  • Loading branch information
gregsh committed Jun 24, 2018
1 parent 51398f9 commit bfc0541
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 24 deletions.
68 changes: 56 additions & 12 deletions gen/org/intellij/clojure/parser/ClojureParser.java

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

9 changes: 6 additions & 3 deletions grammars/clojure.bnf
Expand Up @@ -76,6 +76,7 @@
name("metadata|constructor|reader_.*")=form

methods("reader_macro|metadata")=[toString]
consumeTokenMethod("ignored|symbol_nsq")="fast"
}

root ::= <<parseTree (root_entry)>>
Expand Down Expand Up @@ -115,7 +116,7 @@ literal ::= number | hexnum | rdxnum | ratio | bool | nil | string | char
regexp ::= '#' <<nospace>> string {extends=literal}
access ::= ('.' | '.-') symbol
left access_left ::= !<<space>> '.'
constructor ::= '#' symbol form
constructor ::= '#' ignored symbol ignored form
metadata ::= ("^" | "#^") (string | symbol | keyword | map)
reader_macro ::= "'" | "~" | "~@" | "@" | "`" | "#_" | "#'" | "#=" | symbolic_value | reader_cond | map_ns_prefix
private symbolic_value ::= '##' &sym {pin=1}
Expand All @@ -131,5 +132,7 @@ private meta items_entry ::= (not_eof <<recover>>) <<param>> {pin=1 recoverWhile
private list_body ::= <<items !')' form>>
private set_body ::= <<items !'}' form>>
private vec_body ::= <<items !']' form>>
private map_body ::= <<items !'}' map_entry>>
private map_entry ::= form form {pin=1}
private map_body ::= ignored <<items !'}' map_entry>>
private map_entry ::= form ignored form ignored {pin=2}

private ignored ::= (&'#_' form) * {pin(".*")=1}
6 changes: 5 additions & 1 deletion testData/highlighting/ClojureFixes.clj
Expand Up @@ -75,4 +75,8 @@
@<warning>not-to-resolve</warning>
#:some-ns {:some-key <warning>not-to-resolve</warning>}
(#'clojure.uuid/default-uuid-reader)
(clojure.uuid/<warning>default-uuid-reader</warning>)
(clojure.uuid/<warning>default-uuid-reader</warning>)

(def #_comment named-zero 0)
{#_0 #_1 :a #_'(xxx) 'a :b 'b #_2 #_3}
# #_comment dbg 10
84 changes: 84 additions & 0 deletions testData/parser/CommentedForms.txt
@@ -0,0 +1,84 @@
CFileImpl:a.clj
CListImpl(C_LIST)
PsiElement(()('(')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('def')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(sym)('cc')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('n')
PsiWhiteSpace(' ')
CLiteralImpl(C_LITERAL)
PsiElement(number)('0')
PsiElement())(')')
PsiWhiteSpace(' ')
CMapImpl(C_MAP)
PsiElement({)('{')
CLiteralImpl(C_LITERAL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(number)('0')
PsiWhiteSpace(' ')
CLiteralImpl(C_LITERAL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(number)('1')
PsiWhiteSpace(' ')
CKeywordImpl(C_KEYWORD)
PsiElement(:)(':')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('a')
PsiWhiteSpace(' ')
CListImpl(C_LIST)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
CReaderMacroImpl(C_READER_MACRO)
PsiElement(')(''')
PsiElement(()('(')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('xxx')
PsiElement())(')')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(')(''')
PsiElement(sym)('a')
PsiWhiteSpace(' ')
CKeywordImpl(C_KEYWORD)
PsiElement(:)(':')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('b')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(')(''')
PsiElement(sym)('b')
PsiWhiteSpace(' ')
CLiteralImpl(C_LITERAL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(number)('2')
PsiWhiteSpace(' ')
CLiteralImpl(C_LITERAL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(number)('3')
PsiElement(})('}')
PsiWhiteSpace(' ')
CConstructorImpl(C_CONSTRUCTOR)
PsiElement(#)('#')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
CReaderMacroImpl(C_READER_MACRO)
PsiElement(#_)('#_')
PsiElement(sym)('asd')
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('dbg')
PsiWhiteSpace(' ')
CLiteralImpl(C_LITERAL)
PsiElement(number)('10')
2 changes: 1 addition & 1 deletion testData/parser/SimpleRecover.txt
Expand Up @@ -48,5 +48,5 @@ CFileImpl:a.clj
PsiWhiteSpace(' ')
CSymbolImpl(C_SYMBOL)
PsiElement(sym)('sym')
PsiErrorElement:'.' or '/' expected, got ')'
PsiErrorElement:'.' expected, got ')'
PsiElement())(')')
6 changes: 6 additions & 0 deletions tests/lang/completion-tests.kt
Expand Up @@ -2,6 +2,7 @@ package org.intellij.clojure.lang

import com.intellij.codeInsight.completion.CompletionType
import com.intellij.codeInsight.lookup.Lookup.REPLACE_SELECT_CHAR
import com.intellij.openapi.util.registry.Registry
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase

/**
Expand All @@ -14,6 +15,11 @@ class ClojureCompletionTest : LightPlatformCodeInsightFixtureTestCase() {
val STR_ALIAS = "(alias 'str clojure.string)"
}

override fun setUp() {
super.setUp()
Registry.get("ide.completion.variant.limit").setValue(10000)
}

fun testCoreNs1() = doTest("<caret>", "clojure.core", "clojure.core")
fun testCoreNs2() = doTest(":<caret>", "clojure.core", ":clojure.core")
fun testCoreDefn1() = doTest("(<caret>)", "defn", "(defn)")
Expand Down
17 changes: 10 additions & 7 deletions tests/lang/language-tests.kt
Expand Up @@ -74,6 +74,7 @@ class ClojureParsingTest : ClojureParsingTestCase(ClojureParserDefinition()) {
fun testSimpleRecover2() = doCodeTest("(a))(b)")
fun testSimpleFixes() = doCodeTest(".1 x .-;comment\n1;unclosed eof\n\"x")
fun testMapPrefix() = doCodeTest("#:asd{:a 1 :b #::{:c 2} #::as {} :s1 #:: {} :s2 #:a {} :s3 #: a{} :s4 #:: a{} ")
fun testCommentedForms() = doCodeTest("(def #_cc n 0) {#_0 #_1 :a #_'(xxx) 'a :b 'b #_2 #_3} # #_asd dbg 10")

fun testParseClojureLang() = walkAndParse(::walkClojureLang)
// fun testParseWellKnownLibs() = walkAndParse(::walkKnownLibs)
Expand All @@ -92,7 +93,7 @@ abstract class ClojureParsingTestCase(o: ClojureParserDefinitionBase) : ParsingT
addExplicitExtension(LanguageBraceMatching.INSTANCE, ClojureLanguage, ClojureBraceMatcher())
}

fun walkAndParse(walker: ((Path, String) -> Unit) -> Unit): Unit {
fun walkAndParse(walker: ((Path, String) -> Unit) -> Unit) {
val stat = object {
var duration = System.currentTimeMillis()
var files: Int = 0
Expand All @@ -107,9 +108,11 @@ abstract class ClojureParsingTestCase(o: ClojureParserDefinitionBase) : ParsingT
for (o in SyntaxTraverser.psiTraverser(psiFile)) {
stat.nodes++
val elementType = o.elementType
val message =
if (elementType == TokenType.BAD_CHARACTER) "bad char '${o.text}'"
else if (o is PsiErrorElement) "error: ${o.errorDescription}" else null
val message = when {
elementType == TokenType.BAD_CHARACTER -> "bad char '${o.text}'"
o is PsiErrorElement -> "error: ${o.errorDescription}"
else -> null
}
if (message != null) {
stat.errors++
println("${psiFile.name} [${o.textRange.startOffset}]: $message")
Expand All @@ -126,7 +129,7 @@ abstract class ClojureParsingTestCase(o: ClojureParserDefinitionBase) : ParsingT
}

class ClojureHighlightingTest : LightPlatformCodeInsightFixtureTestCase() {
override fun getTestDataPath() = TEST_DATA_PATH + "/highlighting"
override fun getTestDataPath() = "$TEST_DATA_PATH/highlighting"
override fun setUp() {
super.setUp()
FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, myFixture.project, null)
Expand All @@ -138,15 +141,15 @@ class ClojureHighlightingTest : LightPlatformCodeInsightFixtureTestCase() {
fun testClojureLang() = walkAndHighlight(::walkClojureLang)
fun testClojureScript() = walkAndHighlight(::walkClojureScriptLang)

fun doTest(extension: String): Unit {
private fun doTest(extension: String) {
myFixture.configureByFile(getTestName(false) + ".$extension")
myFixture.checkHighlighting()
}

// fun testClojureFile() = "/clojure/core.clj".let { file ->
// walkAndHighlight { block -> walkFs(CLJ_LIB_FS, file, block) } }

fun walkAndHighlight(walker: ((Path, String) -> Unit) -> Unit) {
private fun walkAndHighlight(walker: ((Path, String) -> Unit) -> Unit) {
val stat = object {
var duration = System.currentTimeMillis()
var files: Int = 0
Expand Down

0 comments on commit bfc0541

Please sign in to comment.