Skip to content

Commit

Permalink
Fix remaining problems #409
Browse files Browse the repository at this point in the history
  • Loading branch information
giraud committed Jul 5, 2023
1 parent bae5f28 commit b6ff0be
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 35 deletions.
37 changes: 18 additions & 19 deletions src/main/java/com/reason/lang/ocaml/OclParser.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.reason.lang.ocaml;

import com.intellij.lang.*;
import com.intellij.openapi.project.*;
import com.intellij.psi.*;
import com.intellij.psi.tree.*;
import com.reason.lang.*;
import com.reason.lang.core.type.*;
Expand All @@ -15,16 +13,6 @@ public OclParser(boolean isSafe) {
super(isSafe);
}

public static ASTNode parseOcamlNode(@NotNull ILazyParseableElementType root, @NotNull ASTNode chameleon) {
PsiElement parentElement = chameleon.getTreeParent().getPsi();
Project project = parentElement.getProject();

PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, new OclLexer(), root.getLanguage(), chameleon.getChars());
OclParser parser = new OclParser(true);

return parser.parse(root, builder).getFirstChildNode();
}

@Override
protected ORParser<OclTypes> getORParser(@NotNull PsiBuilder builder) {
return new OclParserState(builder, myIsSafe);
Expand Down Expand Up @@ -344,8 +332,6 @@ private void parseGt() {
popEndUntil(myTypes.C_OBJECT);
advance().end();
popEnd();
} else {
//
}
}
}
Expand Down Expand Up @@ -753,6 +739,7 @@ private void parseFun() {
}
}

@SuppressWarnings("StatementWithEmptyBody")
private void parseEq() {
if (in(myTypes.H_NAMED_PARAM_DECLARATION) && isFoundScope(myTypes.LPAREN)) {
// let fn ?(x |> = <| ...
Expand All @@ -774,12 +761,23 @@ private void parseEq() {
popEndUntil(myTypes.C_SIG_EXPR).popEnd().advance();
} else if (strictlyInAny(myTypes.C_LET_DECLARATION, myTypes.C_MODULE_DECLARATION)) {
// if inside a let binding, do nothing
if (isFound(myTypes.C_LET_DECLARATION) && !isCurrent(myTypes.C_LET_BINDING)) {
if (isFound(myTypes.C_LET_DECLARATION)) {
int letPos = getIndex();
if (in(myTypes.C_LET_BINDING, null, letPos, false)) {
// in a function :: let (x) y z |> = <| ...
popEndUntil(myTypes.C_FUNCTION_EXPR).advance()
.mark(myTypes.C_FUNCTION_BODY);
if (isCurrent(myTypes.C_LET_BINDING) && is(myTypes.H_PLACE_HOLDER)) {
// inside a let binding, it might be a binary condition
updateLatestComposite(myTypes.C_BINARY_CONDITION);
markHolderBefore(0, myTypes.H_PLACE_HOLDER);
} else if (in(myTypes.C_LET_BINDING, null, letPos, false)) {
int letBinding = getIndex();
if (in(myTypes.C_FUNCTION_EXPR, null, letBinding, false)) {
// in a function :: let (x) y z |> = <| ...
popEndUntil(myTypes.C_FUNCTION_EXPR).advance()
.mark(myTypes.C_FUNCTION_BODY);
} else {
// inside a let binding, but not a function expression. it might be a binary condition
markBefore(letBinding - 1, myTypes.C_BINARY_CONDITION).
popEndUntil(myTypes.C_BINARY_CONDITION);
}
} else {
// let x |> = <| ...
popEndUntilIndex(letPos).advance().
Expand Down Expand Up @@ -1265,6 +1263,7 @@ private void parseExternal() {
mark(myTypes.C_EXTERNAL_DECLARATION);
}

@SuppressWarnings("StatementWithEmptyBody")
private void parseType() {
if (is(myTypes.C_MODULE_DECLARATION)) {
// module |>type<| M = ...
Expand Down
48 changes: 32 additions & 16 deletions src/test/java/com/reason/lang/ocaml/LetParsingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,15 @@ public void test_GH_278() {
// https://github.com/giraud/reasonml-idea-plugin/issues/406
@Test
public void test_GH_406() {
RPsiLet e = firstOfType(parseCode("let is_uppercase s =\n" +
" let x = 0 in\n" +
" let open CamomileLibraryDefault.Camomile in\n" +
" let open UReStr in\n" +
" let open UReStr.Make(UTF8) in\n" +
" let y = 0 in\n" +
" let z = 0 in\n" +
" false"), RPsiLet.class);
RPsiLet e = firstOfType(parseCode("""
let is_uppercase s =
let x = 0 in
let open CamomileLibraryDefault.Camomile in
let open UReStr in
let open UReStr.Make(UTF8) in
let y = 0 in
let z = 0 in
false"""), RPsiLet.class);

assertNoParserError(e);
RPsiFunctionBody eb = e.getFunction().getBody();
Expand Down Expand Up @@ -379,32 +380,47 @@ public void test_GH_407() {
// https://github.com/giraud/reasonml-idea-plugin/issues/409
@Test
public void test_GH_409() {
RPsiLet e = firstOfType(parseCode("let f () =\n" +
" let b : bool = 1 = 1 in\n" +
" let x = 0 in\n" +
" x"), RPsiLet.class);
RPsiLet e = firstOfType(parseCode("""
let f () =
let b : bool = 1 = 1 in
let x = 0 in
x"""), RPsiLet.class);

assertNoParserError(e);
RPsiFunctionBody eb = e.getFunction().getBody();
RPsiLet[] ebls = PsiTreeUtil.getChildrenOfType(eb, RPsiLet.class);
assertEquals("let b : bool = 1 = 1", ebls[0].getText());
assertEquals("1 = 1", PsiTreeUtil.getChildOfType(ebls[0].getBinding(), RPsiBinaryCondition.class).getText());
assertEquals("let x = 0", ebls[1].getText());
assertSize(2, ebls);
}

// https://github.com/giraud/reasonml-idea-plugin/issues/409
@Test
public void test_GH_409a() {
RPsiLet e = firstOfType(parseCode("let f () =\n" +
" let b : bool = ignore () = () in\n" +
" let x = 0 in\n" +
" x"), RPsiLet.class);
RPsiLet e = firstOfType(parseCode("""
let f () =
let b : bool = ignore () = () in
let x = 0 in
x"""), RPsiLet.class);

assertNoParserError(e);
RPsiFunctionBody eb = e.getFunction().getBody();
RPsiLet[] ebls = PsiTreeUtil.getChildrenOfType(eb, RPsiLet.class);
assertEquals("let b : bool = ignore () = ()", ebls[0].getText());
assertEquals("ignore () = ()", PsiTreeUtil.getChildOfType(ebls[0].getBinding(), RPsiBinaryCondition.class).getText());
assertEquals("let x = 0", ebls[1].getText());
assertSize(2, ebls);
}

// https://github.com/giraud/reasonml-idea-plugin/issues/409
@Test
public void test_GH_409_binary_condition() {
RPsiLet e = firstOfType(parseCode("let b = ignore \"\" = ()"), RPsiLet.class);

assertNoParserError(e);
assertEquals("ignore \"\" = ()", e.getBinding().getText());
assertEquals("ignore \"\" = ()", PsiTreeUtil.getChildOfType(e.getBinding(), RPsiBinaryCondition.class).getText());
assertEquals("ignore \"\"", PsiTreeUtil.findChildOfType(e, RPsiFunctionCall.class).getText());
}
}

0 comments on commit b6ff0be

Please sign in to comment.