From 9b05a644b87ddc9f70276c165303a3e46fb24623 Mon Sep 17 00:00:00 2001 From: Alex Berezhnykh Date: Tue, 11 Apr 2023 17:30:30 +0300 Subject: [PATCH] wip --- rider-fsharp/build.gradle.kts | 15 ++- .../fileTypes/fsharp/FSharpAstFactory.kt | 5 - .../fileTypes/fsharp/FSharpDummyParser.kt | 115 ++++++++++++++++++ .../fsharp/FSharpParserDefinition.kt | 40 ++++-- .../FSharpSyntaxHighlighterFactory.kt | 4 +- .../fsharp/lexer/FSharpTokenType.java | 19 ++- .../fsharp/psi/FSharpElementTypes.kt | 17 +++ .../fileTypes/fsharp/psi/FSharpElements.kt | 16 +++ .../fsharp/psi/FSharpStringLiteralTypes.kt | 24 ++++ .../fileTypes/fsharp/psi/PsiBuilderUtils.kt | 85 +++++++++++++ .../fsharp/psi/impl/FSharpElementTypes.kt | 23 ++++ .../fsharp/psi/impl/FSharpExpressionImpl.kt | 6 + .../fsharp/psi/impl/FSharpFileImpl.kt | 11 ++ ...InterpolatedStringLiteralExpressionImpl.kt | 7 ++ ...rpolatedStringLiteralExpressionPartImpl.kt | 7 ++ .../fsharp/psi/impl/FSharpPsiElementBase.kt | 10 ++ .../psi/impl/StringLiteralExpressionImpl.kt | 7 ++ .../src/main/resources/META-INF/plugin.xml | 1 - .../cases/parser/FSharpDummyParserTest.kt | 28 +++++ .../concatenation 01 - simple.fs | 3 + .../concatenation 01 - simple.txt | 18 +++ .../concatenation 02 - space before plus.fs | 3 + .../concatenation 02 - space before plus.txt | 16 +++ .../concatenation 03 - multiline.fs | 6 + .../concatenation 03 - multiline.txt | 27 ++++ ...ion 04 - multiline with wrong offset 01.fs | 3 + ...on 04 - multiline with wrong offset 01.txt | 18 +++ ...ion 04 - multiline with wrong offset 02.fs | 3 + ...on 04 - multiline with wrong offset 02.txt | 16 +++ .../concatenation 05 - with ident.fs | 1 + .../concatenation 05 - with ident.txt | 7 ++ .../concatenation 06 - unfinished.fs | 1 + .../concatenation 06 - unfinished.txt | 5 + .../concatenation 07 - multiline string.fs | 3 + .../concatenation 07 - multiline string.txt | 15 +++ ...08 - multiline string with wrong offset.fs | 3 + ...8 - multiline string with wrong offset.txt | 14 +++ .../concatenation 09 - with interpolated.fs | 1 + .../concatenation 09 - with interpolated.txt | 13 ++ .../interpolated strings 01.fs | 11 ++ .../interpolated strings 01.txt | 38 ++++++ .../interpolated strings 02 - unfinished.fs | 3 + .../interpolated strings 02 - unfinished.txt | 8 ++ .../regular strings 01.fs | 5 + .../regular strings 01.txt | 11 ++ .../regular strings 02 - unfinished.fs | 3 + .../regular strings 02 - unfinished.txt | 3 + .../unfinished 01 - regular.fs | 2 + .../unfinished 01 - regular.txt | 3 + .../unfinished 02 - interpolated 01.fs | 3 + .../unfinished 02 - interpolated 01.txt | 9 ++ .../unfinished 02 - interpolated 02.fs | 1 + .../unfinished 02 - interpolated 02.txt | 7 ++ 53 files changed, 701 insertions(+), 22 deletions(-) delete mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpAstFactory.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpDummyParser.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElementTypes.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElements.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpStringLiteralTypes.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/PsiBuilderUtils.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpElementTypes.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpExpressionImpl.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpFileImpl.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionImpl.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionPartImpl.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpPsiElementBase.kt create mode 100644 rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/StringLiteralExpressionImpl.kt create mode 100644 rider-fsharp/src/test/kotlin/com/jetbrains/rider/plugins/fsharp/test/cases/parser/FSharpDummyParserTest.kt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.txt create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.fs create mode 100644 rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.txt diff --git a/rider-fsharp/build.gradle.kts b/rider-fsharp/build.gradle.kts index 615b29ba0d..f5492893c3 100644 --- a/rider-fsharp/build.gradle.kts +++ b/rider-fsharp/build.gradle.kts @@ -16,6 +16,12 @@ plugins { kotlin("jvm") version "1.8.0" } +dependencies { + testImplementation("junit:junit:4.13.2") + testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.9.2") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.9.2") +} + apply { plugin("kotlin") } @@ -303,11 +309,18 @@ tasks { dependsOn(generateFSharpLexer, rdgen) } - withType { + val parserTest by register("parserTest") { + useJUnitPlatform() + } + + named("test") { + dependsOn(parserTest) useTestNG { groupByInstances = true } + } + withType { testLogging { showStandardStreams = true exceptionFormat = TestExceptionFormat.FULL diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpAstFactory.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpAstFactory.kt deleted file mode 100644 index e41f282e53..0000000000 --- a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpAstFactory.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.jetbrains.rider.ideaInterop.fileTypes.fsharp - -import com.jetbrains.rider.ideaInterop.fileTypes.RiderASTFactoryBase - -class FSharpAstFactory : RiderASTFactoryBase(FSharpParserDefinition.FSharpElementType) \ No newline at end of file diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpDummyParser.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpDummyParser.kt new file mode 100644 index 0000000000..31784176f1 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpDummyParser.kt @@ -0,0 +1,115 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp + +import com.intellij.lang.ASTNode +import com.intellij.lang.PsiBuilder +import com.intellij.lang.PsiParser +import com.intellij.psi.tree.IElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.lexer.FSharpTokenType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl.FSharpElementTypes +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.parse +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.scanOrRollback +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.whileMakingProgress + +class FSharpDummyParser : PsiParser { + override fun parse(root: IElementType, builder: PsiBuilder): ASTNode { + builder.setWhitespaceSkippedCallback { elementType, _, end -> + if (elementType == FSharpTokenType.NEW_LINE) currentLineStart = end + } + builder.parseFile(root) + return builder.treeBuilt + } + + private fun PsiBuilder.parseFile(fileElementType: IElementType) { + parse(fileElementType) { + whileMakingProgress { + if (!parseDummyExpression()) advanceLexerWithNewLineCounting() + true + } + } + } + + private fun PsiBuilder.getCurrentLineOffset() = currentOffset - currentLineStart + private fun PsiBuilder.parseDummyExpression() = parseConcatenation() + + private fun PsiBuilder.parseConcatenation() = + parse { + val currentIndent = getCurrentLineOffset() + + if (!parseStringExpression()) null + else if (!scanOrRollback { tryParseConcatenationPartAhead(currentIndent) }) null + else { + whileMakingProgress { + scanOrRollback { tryParseConcatenationPartAhead(currentIndent) } + } + FSharpElementTypes.DUMMY_EXPRESSION + } + } + + private fun PsiBuilder.tryParseConcatenationPartAhead(requiredStringIndent: Int): Boolean { + val hasSpaceBeforePlus = rawLookup(-1)?.let { isWhitespaceOrComment(it) } ?: false + + if (tokenType != FSharpTokenType.PLUS) return false + val afterPlusTokenIndent = getCurrentLineOffset() + 1 + advanceLexer() // eat plus token + + // since "123" +"123" is not allowed + if (hasSpaceBeforePlus && currentOffset - afterPlusTokenIndent == 0) return false + + val secondStringOperandIndent = getCurrentLineOffset() + // since + // "123" + // + "123" + // is not allowed + if (secondStringOperandIndent < requiredStringIndent) return false + + // since + // "123" + // more than one space after plus + // + "123" + // is not allowed + if (secondStringOperandIndent == requiredStringIndent && + secondStringOperandIndent - afterPlusTokenIndent > 1 + ) return false + + return parseStringExpression() + } + + private fun PsiBuilder.parseStringExpression() = + parseInterpolatedStringExpression() || parseAnyStringExpression() + + private fun PsiBuilder.parseAnyStringExpression() = + if (tokenType !in FSharpTokenType.ALL_STRINGS) false + else parse { + val interpolated = tokenType in FSharpTokenType.INTERPOLATED_STRINGS + advanceLexerWithNewLineCounting() + if (interpolated) FSharpElementTypes.INTERPOLATED_STRING_LITERAL_EXPRESSION_PART + else FSharpElementTypes.STRING_LITERAL_EXPRESSION + } + + private fun PsiBuilder.parseInterpolatedStringExpression() = + if (tokenType !in FSharpTokenType.INTERPOLATED_STRINGS) false + else parse(FSharpElementTypes.INTERPOLATED_STRING_LITERAL_EXPRESSION) { + var nestingDepth = 0 + whileMakingProgress { + if (tokenType in FSharpTokenType.INTERPOLATED_STRING_STARTS) nestingDepth += 1 + if (tokenType in FSharpTokenType.INTERPOLATED_STRING_ENDS) nestingDepth -= 1 + if (!parseAnyStringExpression()) advanceLexerWithNewLineCounting() + nestingDepth != 0 + } + } + + private fun PsiBuilder.advanceLexerWithNewLineCounting() { + when (tokenType) { + in FSharpTokenType.STRINGS -> { + val lastEndOfLineIndex = tokenText!!.lastIndexOf('\n') + val stringStartIndent = currentOffset + advanceLexer() + if (lastEndOfLineIndex != -1) currentLineStart = stringStartIndent + lastEndOfLineIndex + 1 + } + + else -> advanceLexer() + } + } + + private var currentLineStart = 0 +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpParserDefinition.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpParserDefinition.kt index a2cb901b3b..047a1f8bd7 100644 --- a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpParserDefinition.kt +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/FSharpParserDefinition.kt @@ -1,19 +1,37 @@ package com.jetbrains.rider.ideaInterop.fileTypes.fsharp -import com.intellij.lexer.Lexer +import com.intellij.lang.ASTNode +import com.intellij.lang.ParserDefinition +import com.intellij.lang.PsiParser import com.intellij.openapi.project.Project -import com.intellij.psi.tree.IElementType +import com.intellij.psi.FileViewProvider +import com.intellij.psi.PsiElement import com.intellij.psi.tree.IFileElementType -import com.jetbrains.rider.ideaInterop.fileTypes.RiderFileElementType -import com.jetbrains.rider.ideaInterop.fileTypes.RiderParserDefinitionBase +import com.intellij.psi.tree.TokenSet +import com.intellij.psi.util.PsiUtilCore +import com.jetbrains.rd.platform.util.getLogger import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.lexer.FSharpLexer +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.lexer.FSharpTokenType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl.FSharpElementTypes +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl.FSharpFileImpl -class FSharpParserDefinition : RiderParserDefinitionBase(FSharpFileElementType, FSharpFileType) { - companion object { - val FSharpElementType = IElementType("RIDER_FSHARP", FSharpLanguage) - val FSharpFileElementType = RiderFileElementType("RIDER_FSHARP_FILE", FSharpLanguage, FSharpElementType) - } +class FSharpParserDefinition : ParserDefinition { + private val logger = getLogger() + override fun getWhitespaceTokens() = TokenSet.create(FSharpTokenType.NEW_LINE, FSharpTokenType.WHITESPACE) + override fun createLexer(project: Project?) = FSharpLexer() + override fun createParser(project: Project): PsiParser = FSharpDummyParser() + override fun getCommentTokens(): TokenSet = FSharpTokenType.COMMENTS + override fun getStringLiteralElements(): TokenSet = FSharpTokenType.ALL_STRINGS + override fun createElement(node: ASTNode): PsiElement { + if (node is PsiElement) { + logger.error("Dummy blocks should be lazy and not parsed like this") + return node + } - override fun createLexer(project: Project?): Lexer = FSharpLexer() - override fun getFileNodeType(): IFileElementType = FSharpFileElementType + logger.error("An attempt to parse unexpected element") + return PsiUtilCore.NULL_PSI_ELEMENT + } + + override fun createFile(viewProvider: FileViewProvider) = FSharpFileImpl(viewProvider) + override fun getFileNodeType(): IFileElementType = FSharpElementTypes.FILE } diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/highlighting/FSharpSyntaxHighlighterFactory.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/highlighting/FSharpSyntaxHighlighterFactory.kt index b516011eed..f7b47d9422 100644 --- a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/highlighting/FSharpSyntaxHighlighterFactory.kt +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/highlighting/FSharpSyntaxHighlighterFactory.kt @@ -14,7 +14,7 @@ class FSharpSyntaxHighlighter : SyntaxHighlighterBase() { private val pp_keywords = PP_KEYWORDS.types.map { it to FSharpTextAttributeKeys.PREPROCESSOR_KEYWORD } private val strings = STRINGS.types.map { it to FSharpTextAttributeKeys.STRING } private val interpolated_strings = INTERPOLATED_STRINGS.types.map { it to FSharpTextAttributeKeys.STRING } - private val comments = COMMENTS.types.map { it to FSharpTextAttributeKeys.BLOCK_COMMENT } + private val block_comments = BLOCK_COMMENTS.types.map { it to FSharpTextAttributeKeys.BLOCK_COMMENT } private val numbers = NUMBERS.types.map { it to FSharpTextAttributeKeys.NUMBER } private val ourKeys = mapOf( @@ -22,7 +22,7 @@ class FSharpSyntaxHighlighter : SyntaxHighlighterBase() { BYTECHAR to FSharpTextAttributeKeys.STRING, LINE_COMMENT to FSharpTextAttributeKeys.COMMENT, TokenType.BAD_CHARACTER to HighlighterColors.BAD_CHARACTER - ) + keywords + pp_keywords + comments + strings + interpolated_strings + numbers + ) + keywords + pp_keywords + block_comments + strings + interpolated_strings + numbers } override fun getHighlightingLexer() = FSharpLexer() diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/lexer/FSharpTokenType.java b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/lexer/FSharpTokenType.java index 61d551f97c..6db1a3dc28 100644 --- a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/lexer/FSharpTokenType.java +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/lexer/FSharpTokenType.java @@ -1,5 +1,6 @@ package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.lexer; +import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; @@ -99,7 +100,7 @@ public interface FSharpTokenType { IElementType VERBATIM_INTERPOLATED_STRING_MIDDLE = createToken("VERBATIM_INTERPOLATED_STRING_MIDDLE"); IElementType VERBATIM_INTERPOLATED_STRING_END = createToken("VERBATIM_INTERPOLATED_STRING_END"); IElementType NEW_LINE = createToken("NEW_LINE"); - IElementType WHITESPACE = createToken("WHITESPACE"); + IElementType WHITESPACE = TokenType.WHITE_SPACE; IElementType KEYWORD_STRING_SOURCE_DIRECTORY = createToken("KEYWORD_STRING_SOURCE_DIRECTORY"); IElementType KEYWORD_STRING_SOURCE_FILE = createToken("KEYWORD_STRING_SOURCE_FILE"); IElementType KEYWORD_STRING_LINE = createToken("KEYWORD_STRING_LINE"); @@ -260,17 +261,31 @@ public interface FSharpTokenType { UNFINISHED_TRIPLE_QUOTE_INTERPOLATED_STRING ); + TokenSet ALL_STRINGS = TokenSet.orSet(STRINGS, INTERPOLATED_STRINGS); + + TokenSet INTERPOLATED_STRING_STARTS = TokenSet.create( + REGULAR_INTERPOLATED_STRING_START, + VERBATIM_INTERPOLATED_STRING_START, + TRIPLE_QUOTE_INTERPOLATED_STRING_START + ); + TokenSet INTERPOLATED_STRING_ENDS = TokenSet.create( REGULAR_INTERPOLATED_STRING_END, VERBATIM_INTERPOLATED_STRING_END, TRIPLE_QUOTE_INTERPOLATED_STRING_END ); - TokenSet COMMENTS = TokenSet.create( + TokenSet BLOCK_COMMENTS = TokenSet.create( SHEBANG, BLOCK_COMMENT ); + TokenSet COMMENTS = TokenSet.create( + SHEBANG, + BLOCK_COMMENT, + LINE_COMMENT + ); + TokenSet IDENT_KEYWORDS = TokenSet.create( ABSTRACT, AND, diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElementTypes.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElementTypes.kt new file mode 100644 index 0000000000..1e3ad27d20 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElementTypes.kt @@ -0,0 +1,17 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi + +import com.intellij.lang.ASTNode +import com.intellij.psi.tree.ICompositeElementType +import com.intellij.psi.tree.IElementType +import com.intellij.psi.tree.IFileElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.FSharpLanguage + +class FSharpFileElementType : IFileElementType("FSharpFile", FSharpLanguage) + +open class FSharpElementType(debugName: String, val text: String = debugName) : IElementType(debugName, FSharpLanguage) +abstract class FSharpCompositeElementType(debugName: String) : FSharpElementType(debugName), ICompositeElementType + +inline fun createCompositeElementType(debugName: String, crossinline elementFactory: (FSharpElementType) -> ASTNode) = + object : FSharpCompositeElementType(debugName) { + override fun createCompositeNode() = elementFactory(this) + } diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElements.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElements.kt new file mode 100644 index 0000000000..376cd3e829 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpElements.kt @@ -0,0 +1,16 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile + +interface FSharpElement : PsiElement + +interface FSharpFile : FSharpElement, PsiFile + +interface FSharpExpression : FSharpElement + +interface FSharpStringLiteralExpression : FSharpElement + +interface FSharpInterpolatedStringLiteralExpressionPart : FSharpElement + +interface FSharpInterpolatedStringLiteralExpression : FSharpStringLiteralExpression diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpStringLiteralTypes.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpStringLiteralTypes.kt new file mode 100644 index 0000000000..e4d6379b2e --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/FSharpStringLiteralTypes.kt @@ -0,0 +1,24 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi + +enum class FSharpStringLiteralType { + /** "{string representation}" */ + RegularString, + + /** @"{string representation}" */ + VerbatimString, + + /** """{string representation}""" */ + TripleQuoteString, + + /** $"{string representation}" */ + RegularInterpolatedString, + + /** $@"{string representation}" */ + VerbatimInterpolatedString, + + /** $"""{string representation}""" */ + TripleQuoteInterpolatedString, + + /** "{string representation}"B */ + ByteArray +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/PsiBuilderUtils.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/PsiBuilderUtils.kt new file mode 100644 index 0000000000..b75f0d48e7 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/PsiBuilderUtils.kt @@ -0,0 +1,85 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi + +import com.intellij.lang.PsiBuilder +import com.intellij.psi.tree.IElementType + +/** Repeats given action until lexer advances and action returns true */ +inline fun PsiBuilder.whileMakingProgress(action: PsiBuilder.() -> Boolean) { + var position = currentOffset + while (action() && position != currentOffset) { + position = currentOffset + } +} + +/** + * Parse node of given type if builder was advanced. + * Returns true if node was parsed (and builder was advanced) + */ +inline fun PsiBuilder.parse(nodeType: IElementType, action: PsiBuilder.() -> Unit): Boolean { + val position = rawTokenIndex() + val mark = mark() + action() + return if (position == rawTokenIndex()) { + mark.drop() + false + } else { + mark.done(nodeType) + true + } +} + +/** + * Parse node of returned type, or just scan, if action returns null. + * Returns true if builder was advanced + * */ +inline fun PsiBuilder.parse(action: () -> IElementType?): Boolean { + val mark = mark() + val positionBefore = rawTokenIndex() + + val elementType = action() + if (elementType == null) { + mark.drop() + return positionBefore != rawTokenIndex() + } + return if (positionBefore == rawTokenIndex()) { + mark.drop() + false + } else { + mark.done(elementType) + true + } +} + +/** + * Parse node of returned type, or just scan, if action returns false. + * Returns true if node was parsed (and builder was advanced) + * */ +inline fun PsiBuilder.tryParse(type: IElementType, action: () -> Boolean): Boolean { + val mark = mark() + val positionBefore = rawTokenIndex() + + if (!action()) { + mark.drop() + return false + } + if (positionBefore == rawTokenIndex()) { + mark.drop() + return false + } + + mark.done(type) + return true +} + +/** Scans lexer. Allows to rollback, if action returns true. Returns true if lexer was advanced */ +inline fun PsiBuilder.scanOrRollback(action: () -> Boolean): Boolean { + val mark = mark() + val positionBefore = rawTokenIndex() + + if (!action()) { + mark.rollbackTo() + return false + } + mark.drop() + return positionBefore != rawTokenIndex() +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpElementTypes.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpElementTypes.kt new file mode 100644 index 0000000000..981e2a7163 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpElementTypes.kt @@ -0,0 +1,23 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.* + +object FSharpElementTypes { + val FILE = FSharpFileElementType() + + val DUMMY_EXPRESSION = createCompositeElementType( + "DUMMY_EXPRESSION", ::FSharpExpressionImpl + ) + + val STRING_LITERAL_EXPRESSION = createCompositeElementType( + "STRING_LITERAL_EXPRESSION", ::FSharpStringLiteralExpressionImpl + ) + + val INTERPOLATED_STRING_LITERAL_EXPRESSION_PART = createCompositeElementType( + "INTERPOLATED_STRING_LITERAL_EXPRESSION_PART", ::FSharpInterpolatedStringLiteralExpressionPartImpl + ) + + val INTERPOLATED_STRING_LITERAL_EXPRESSION = createCompositeElementType( + "INTERPOLATED_STRING_LITERAL_EXPRESSION", ::FSharpInterpolatedStringLiteralExpressionImpl + ) +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpExpressionImpl.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpExpressionImpl.kt new file mode 100644 index 0000000000..72b2a1a999 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpExpressionImpl.kt @@ -0,0 +1,6 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpExpression + +open class FSharpExpressionImpl(type: FSharpElementType) : FSharpPsiElementBase(type), FSharpExpression diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpFileImpl.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpFileImpl.kt new file mode 100644 index 0000000000..80f1f2859d --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpFileImpl.kt @@ -0,0 +1,11 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.intellij.extapi.psi.PsiFileBase +import com.intellij.psi.FileViewProvider +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.FSharpFileType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.FSharpLanguage +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpFile + +class FSharpFileImpl(viewProvider: FileViewProvider) : FSharpFile, PsiFileBase(viewProvider, FSharpLanguage) { + override fun getFileType() = FSharpFileType +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionImpl.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionImpl.kt new file mode 100644 index 0000000000..192fde1837 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionImpl.kt @@ -0,0 +1,7 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpInterpolatedStringLiteralExpression + +class FSharpInterpolatedStringLiteralExpressionImpl(type: FSharpElementType) : FSharpPsiElementBase(type), + FSharpInterpolatedStringLiteralExpression diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionPartImpl.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionPartImpl.kt new file mode 100644 index 0000000000..21d5996820 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpInterpolatedStringLiteralExpressionPartImpl.kt @@ -0,0 +1,7 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpInterpolatedStringLiteralExpressionPart + +class FSharpInterpolatedStringLiteralExpressionPartImpl(type: FSharpElementType) : FSharpPsiElementBase(type), + FSharpInterpolatedStringLiteralExpressionPart diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpPsiElementBase.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpPsiElementBase.kt new file mode 100644 index 0000000000..841ee09948 --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/FSharpPsiElementBase.kt @@ -0,0 +1,10 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.impl.source.tree.CompositePsiElement +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElement +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElementType + +abstract class FSharpPsiElementBase(type: FSharpElementType) : CompositePsiElement(type), FSharpElement { + override fun toString() = StringUtil.trimEnd(javaClass.simpleName, "Impl") +} diff --git a/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/StringLiteralExpressionImpl.kt b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/StringLiteralExpressionImpl.kt new file mode 100644 index 0000000000..308e2c473c --- /dev/null +++ b/rider-fsharp/src/main/java/com/jetbrains/rider/ideaInterop/fileTypes/fsharp/psi/impl/StringLiteralExpressionImpl.kt @@ -0,0 +1,7 @@ +package com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.impl + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpElementType +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.psi.FSharpStringLiteralExpression + +class FSharpStringLiteralExpressionImpl(type: FSharpElementType) : FSharpPsiElementBase(type), + FSharpStringLiteralExpression diff --git a/rider-fsharp/src/main/resources/META-INF/plugin.xml b/rider-fsharp/src/main/resources/META-INF/plugin.xml index 0a9c1baa46..8385aad4b6 100644 --- a/rider-fsharp/src/main/resources/META-INF/plugin.xml +++ b/rider-fsharp/src/main/resources/META-INF/plugin.xml @@ -12,7 +12,6 @@ - diff --git a/rider-fsharp/src/test/kotlin/com/jetbrains/rider/plugins/fsharp/test/cases/parser/FSharpDummyParserTest.kt b/rider-fsharp/src/test/kotlin/com/jetbrains/rider/plugins/fsharp/test/cases/parser/FSharpDummyParserTest.kt new file mode 100644 index 0000000000..eb96a4921b --- /dev/null +++ b/rider-fsharp/src/test/kotlin/com/jetbrains/rider/plugins/fsharp/test/cases/parser/FSharpDummyParserTest.kt @@ -0,0 +1,28 @@ +package com.jetbrains.rider.plugins.fsharp.test.cases.parser + +import com.jetbrains.rider.ideaInterop.fileTypes.fsharp.FSharpParserDefinition +import com.jetbrains.rider.test.RiderFrontendParserTest + +class FSharpDummyParserTests : RiderFrontendParserTest("", "fs", FSharpParserDefinition()) { + fun `test concatenation 01 - simple`() = doTest() + fun `test concatenation 02 - space before plus`() = doTest() + fun `test concatenation 03 - multiline`() = doTest() + //TODO: compromise to avoid fair parsing + fun `test concatenation 04 - multiline with wrong offset 01`() = doTest() + fun `test concatenation 04 - multiline with wrong offset 02`() = doTest() + fun `test concatenation 05 - with ident`() = doTest() + fun `test concatenation 06 - unfinished`() = doTest() + fun `test concatenation 07 - multiline string`() = doTest() + fun `test concatenation 08 - multiline string with wrong offset`() = doTest() + fun `test concatenation 09 - with interpolated`() = doTest() + + fun `test regular strings 01`() = doTest() + fun `test regular strings 02 - unfinished`() = doTest() + + fun `test interpolated strings 01`() = doTest() + fun `test interpolated strings 02 - unfinished`() = doTest() + + fun `test unfinished 01 - regular`() = doTest() + fun `test unfinished 02 - interpolated 01`() = doTest() + fun `test unfinished 02 - interpolated 02`() = doTest() +} diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.fs new file mode 100644 index 0000000000..4a8bf4e19c --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.fs @@ -0,0 +1,3 @@ +"123"+(*comment*)"123" + +"123"(*comment*)+ "123" \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.txt new file mode 100644 index 0000000000..368cfdc6cf --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 01 - simple.txt @@ -0,0 +1,18 @@ +FSharpFile + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiElement(PLUS)('+') + PsiComment(BLOCK_COMMENT)('(*comment*)') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiComment(BLOCK_COMMENT)('(*comment*)') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.fs new file mode 100644 index 0000000000..d0f5a48163 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.fs @@ -0,0 +1,3 @@ +"123" +"123" + +"123"+ "123" \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.txt new file mode 100644 index 0000000000..a22774d6a0 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 02 - space before plus.txt @@ -0,0 +1,16 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.fs new file mode 100644 index 0000000000..3039b3086b --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.fs @@ -0,0 +1,6 @@ +let _ = + id "123" + + + "123" + + + "123" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.txt new file mode 100644 index 0000000000..b5b31441c3 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 03 - multiline.txt @@ -0,0 +1,27 @@ +FSharpFile + PsiElement(LET)('let') + PsiWhiteSpace(' ') + PsiElement(UNDERSCORE)('_') + PsiWhiteSpace(' ') + PsiElement(EQUALS)('=') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + PsiElement(IDENT)('id') + PsiWhiteSpace(' ') + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.fs new file mode 100644 index 0000000000..c61dd6c4a2 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.fs @@ -0,0 +1,3 @@ +let _ = + id "123" + + "123" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.txt new file mode 100644 index 0000000000..24b3ec85d4 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 01.txt @@ -0,0 +1,18 @@ +FSharpFile + PsiElement(LET)('let') + PsiWhiteSpace(' ') + PsiElement(UNDERSCORE)('_') + PsiWhiteSpace(' ') + PsiElement(EQUALS)('=') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + PsiElement(IDENT)('id') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.fs new file mode 100644 index 0000000000..80c28b90af --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.fs @@ -0,0 +1,3 @@ +let _ = + "123" + + "123" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.txt new file mode 100644 index 0000000000..5ced0a492e --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 04 - multiline with wrong offset 02.txt @@ -0,0 +1,16 @@ +FSharpFile + PsiElement(LET)('let') + PsiWhiteSpace(' ') + PsiElement(UNDERSCORE)('_') + PsiWhiteSpace(' ') + PsiElement(EQUALS)('=') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.fs new file mode 100644 index 0000000000..c8dd81e33b --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.fs @@ -0,0 +1 @@ +"123" + x diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.txt new file mode 100644 index 0000000000..ae41068539 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 05 - with ident.txt @@ -0,0 +1,7 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + PsiElement(IDENT)('x') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.fs new file mode 100644 index 0000000000..65ea362f35 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.fs @@ -0,0 +1 @@ +"123" + diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.txt new file mode 100644 index 0000000000..fc5120ddf3 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 06 - unfinished.txt @@ -0,0 +1,5 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.fs new file mode 100644 index 0000000000..c8ca7099cf --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.fs @@ -0,0 +1,3 @@ +let _ = " + +123" + "123" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.txt new file mode 100644 index 0000000000..db1eb87368 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 07 - multiline string.txt @@ -0,0 +1,15 @@ +FSharpFile + PsiElement(LET)('let') + PsiWhiteSpace(' ') + PsiElement(UNDERSCORE)('_') + PsiWhiteSpace(' ') + PsiElement(EQUALS)('=') + PsiWhiteSpace(' ') + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"\n\n123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.fs new file mode 100644 index 0000000000..979f39b33d --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.fs @@ -0,0 +1,3 @@ +let _ = " + +123" + "123" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.txt new file mode 100644 index 0000000000..635902504c --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 08 - multiline string with wrong offset.txt @@ -0,0 +1,14 @@ +FSharpFile + PsiElement(LET)('let') + PsiWhiteSpace(' ') + PsiElement(UNDERSCORE)('_') + PsiWhiteSpace(' ') + PsiElement(EQUALS)('=') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"\n\n123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.fs new file mode 100644 index 0000000000..b72812a319 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.fs @@ -0,0 +1 @@ +"123" + $"1 {2} 3" \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.txt new file mode 100644 index 0000000000..8ec1a57b09 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/concatenation 09 - with interpolated.txt @@ -0,0 +1,13 @@ +FSharpFile + FSharpExpression + FSharpStringLiteralExpression + PsiElement(STRING)('"123"') + PsiWhiteSpace(' ') + PsiElement(PLUS)('+') + PsiWhiteSpace(' ') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_START)('$"1 {') + PsiElement(INT32)('2') + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_END)('} 3"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.fs new file mode 100644 index 0000000000..32644738ba --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.fs @@ -0,0 +1,11 @@ +$"1" + +$"1 {2} 3" + +$@"1 {2} 3" + +$@"1" + +$"""1""" + +$"""1 {2} 3""" \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.txt new file mode 100644 index 0000000000..f6ef6804ae --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 01.txt @@ -0,0 +1,38 @@ +FSharpFile + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING)('$"1"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_START)('$"1 {') + PsiElement(INT32)('2') + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_END)('} 3"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(VERBATIM_INTERPOLATED_STRING_START)('$@"1 {') + PsiElement(INT32)('2') + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(VERBATIM_INTERPOLATED_STRING_END)('} 3"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(VERBATIM_INTERPOLATED_STRING)('$@"1"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(TRIPLE_QUOTED_STRING)('$"""1"""') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(TRIPLE_QUOTE_INTERPOLATED_STRING_START)('$"""1 {') + PsiElement(INT32)('2') + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(TRIPLE_QUOTED_STRING_END)('} 3"""') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.fs new file mode 100644 index 0000000000..40d8474a11 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.fs @@ -0,0 +1,3 @@ +$"1 {2 + +3 \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.txt new file mode 100644 index 0000000000..7d37e4b02a --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/interpolated strings 02 - unfinished.txt @@ -0,0 +1,8 @@ +FSharpFile + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_START)('$"1 {') + PsiElement(INT32)('2') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + PsiElement(INT32)('3') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.fs new file mode 100644 index 0000000000..94ab991144 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.fs @@ -0,0 +1,5 @@ +"1" + +@"123" + +"""1""" \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.txt new file mode 100644 index 0000000000..208ffaeb2f --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 01.txt @@ -0,0 +1,11 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(STRING)('"1"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpStringLiteralExpression + PsiElement(VERBATIM_STRING)('@"123"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + FSharpStringLiteralExpression + PsiElement(TRIPLE_QUOTED_STRING)('"""1"""') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.fs new file mode 100644 index 0000000000..bebcf097b3 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.fs @@ -0,0 +1,3 @@ +"1 2 + +3 \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.txt new file mode 100644 index 0000000000..3b1f7831d5 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/regular strings 02 - unfinished.txt @@ -0,0 +1,3 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(UNFINISHED_STRING)('"1 2\n\n3') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.fs new file mode 100644 index 0000000000..ef7b9789d9 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.fs @@ -0,0 +1,2 @@ +" +1 diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.txt new file mode 100644 index 0000000000..6c12e8c01a --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 01 - regular.txt @@ -0,0 +1,3 @@ +FSharpFile + FSharpStringLiteralExpression + PsiElement(UNFINISHED_STRING)('"\n1') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.fs new file mode 100644 index 0000000000..3c12ca3a69 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.fs @@ -0,0 +1,3 @@ +$" { +1 +" diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.txt new file mode 100644 index 0000000000..d53b9b3dd5 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 01.txt @@ -0,0 +1,9 @@ +FSharpFile + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_START)('$" {') + PsiWhiteSpace('\n') + PsiElement(INT32)('1') + PsiWhiteSpace('\n') + FSharpStringLiteralExpression + PsiElement(UNFINISHED_STRING)('"') \ No newline at end of file diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.fs b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.fs new file mode 100644 index 0000000000..6146c77a28 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.fs @@ -0,0 +1 @@ +$" { } diff --git a/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.txt b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.txt new file mode 100644 index 0000000000..d44ed28e49 --- /dev/null +++ b/rider-fsharp/testData/parser/FSharpDummyParserTests/unfinished 02 - interpolated 02.txt @@ -0,0 +1,7 @@ +FSharpFile + FSharpInterpolatedStringLiteralExpression + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_START)('$" {') + PsiWhiteSpace(' ') + FSharpInterpolatedStringLiteralExpressionPart + PsiElement(REGULAR_INTERPOLATED_STRING_MIDDLE)('}') \ No newline at end of file