diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..80824f1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# prettier-lpc-vscode Changelog + +## 0.0.76 + +- Fix: [[FluffOS] Autoformatter does not know what to do with default parameters in function definition #36](https://github.com/jlchmura/prettier-lpc-vscode/issues/36) + +## 0.0.75 + +- Fix bad build deployed to marketplace diff --git a/README.md b/README.md index 50445df..d5498d2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,11 @@ VSCode extension to format LPC (Lars Pensjö C) files with [Prettier](https://prettier.io/). It is written mainly for the [LDMud](http://www.ldmud.eu/) flavor of LPC, but includes support for most FluffOS syntax as well. ### WARNING -This extension is a very early release. **It may break your code**. Use at your own risk. +This extension should still be considered an early release. **It may break your code**. Use at your own risk. + +## Changelog + +See [CHANGELOG.md](CHANGELOG.md). ## Installation Install from the VS Code Marketplace: [prettier-lpc-vscode](https://marketplace.visualstudio.com/items?itemName=jlchmura.prettier-lpc-vscode) diff --git a/package.json b/package.json index 35fa796..a64ad98 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "license": "MIT", "name": "prettier-lpc-vscode", - "version": "0.0.75", + "version": "0.0.76", "engines": { "vscode": "^1.63.0" }, @@ -20,6 +20,7 @@ "cli": "npx tsc && node --enable-source-maps ./build/cli.js", "build": "npx tsc", "build:ext": "esbuild ./src/extension.ts --bundle --outfile=build/extension.js --external:vscode --format=cjs --platform=node", + "vscode:prepublish": "npm run build:ext", "vsce:package": "vsce package", "vsce:publish": "vsce publish", "watch": "tsc --watch --project ./" diff --git a/src/nodeTypes/assignmentExpression.ts b/src/nodeTypes/assignmentExpression.ts index dbf57b3..daf7b74 100644 --- a/src/nodeTypes/assignmentExpression.ts +++ b/src/nodeTypes/assignmentExpression.ts @@ -7,5 +7,5 @@ export class AssignmentExpressionNode extends LPCNode { public override type: string | undefined = ASSIGN_EXP_TYPE; public left: IdentifierNode | undefined; public right: LPCNode | undefined; - public operator: string | undefined; + public operator: string | undefined; } diff --git a/src/nodeTypes/functionDeclaration.ts b/src/nodeTypes/functionDeclaration.ts index 849962a..879ec75 100644 --- a/src/nodeTypes/functionDeclaration.ts +++ b/src/nodeTypes/functionDeclaration.ts @@ -12,3 +12,8 @@ export class FunctionDeclarationNode extends BaseDeclarationNode { /** When true indicates that this is a function stub instead of an actual function declaration */ public isStub = false; } + +export class ParameterDefaultValueNode extends LPCNode { + public override type: string | undefined = "parameterDefaultValue"; + public value: LPCNode | undefined; +} \ No newline at end of file diff --git a/src/parser/lpcParser.ts b/src/parser/lpcParser.ts index a68b544..0e38842 100644 --- a/src/parser/lpcParser.ts +++ b/src/parser/lpcParser.ts @@ -33,7 +33,7 @@ import { ForStatementNode, MultiExpressionNode, } from "../nodeTypes/forStatement"; -import { FunctionDeclarationNode } from "../nodeTypes/functionDeclaration"; +import { FunctionDeclarationNode, ParameterDefaultValueNode } from "../nodeTypes/functionDeclaration"; import { IdentifierNode } from "../nodeTypes/identifier"; import { InheritNode } from "../nodeTypes/inherit"; import { @@ -1804,8 +1804,9 @@ export class LPCParser { return this.parseStructDefinition(structTypeNode, parent); } - if (t == TokenType.AssignmentOperator) { + if (t == TokenType.AssignmentOperator || t == TokenType.Colon) { if (allowDecl && (typeNode || modNodes.length > 0)) { + const assignmentToken = t; this.scanner.scan(); // this is definitely a declaration // which means the assignment is an init @@ -1824,12 +1825,19 @@ export class LPCParser { // get next token & parse the init expression t = this.scanner.scan(); - const initExp = this.parseToken( + let initExp = this.parseToken( t, varDecl, ParseExpressionFlag.StatementOnly ); + if (assignmentToken == TokenType.Colon && initExp) { + const defVal = initExp; + initExp = new ParameterDefaultValueNode(initExp.start, initExp.end, [], varDecl); + (initExp as ParameterDefaultValueNode).value = defVal; + defVal.parent = initExp; + } + return this.parseVariableDeclaration( varDecl, parent, diff --git a/src/plugin/print/function.ts b/src/plugin/print/function.ts index 176d446..68ce9c3 100644 --- a/src/plugin/print/function.ts +++ b/src/plugin/print/function.ts @@ -1,10 +1,8 @@ import { Doc, util } from "prettier"; import { builders } from "prettier/doc"; -import { CodeBlockNode } from "../../nodeTypes/codeBlock"; -import { FunctionDeclarationNode } from "../../nodeTypes/functionDeclaration"; +import { FunctionDeclarationNode, ParameterDefaultValueNode } from "../../nodeTypes/functionDeclaration"; import { ParentExpressionNode } from "../../nodeTypes/memberExpression"; import { ReturnNode } from "../../nodeTypes/returnNode"; -import { VariableDeclarationNode } from "../../nodeTypes/variableDeclaration"; import { printSuffixComments } from "./comment"; import { PrintNodeFunction } from "./shared"; @@ -61,6 +59,15 @@ export const printFunction: PrintNodeFunction = ( return arr; }; +export const printParamDefaultValue: PrintNodeFunction = ( + node, + path, + options, + printChildren +) => { + return path.call(printChildren, "value"); +} + export const printReturn: PrintNodeFunction = ( node, path, diff --git a/src/plugin/print/tests/index.spec.ts b/src/plugin/print/tests/index.spec.ts index ea22d8b..3b81dae 100644 --- a/src/plugin/print/tests/index.spec.ts +++ b/src/plugin/print/tests/index.spec.ts @@ -184,7 +184,9 @@ describe("prettier-lpc plugin", () => { formatted = format(textNestedParenBlocksWithLogicalExpr); expect(formatted).toMatchSnapshot("nested-parens-with-logical-exp"); - formatted = format(`test() { if((obj = present("armour", TP)) && obj->query_worn()) {} }`); + formatted = format( + `test() { if((obj = present("armour", TP)) && obj->query_worn()) {} }` + ); expect(formatted).toMatchSnapshot("nested-parens-with-logical-exp"); }); @@ -751,7 +753,9 @@ move_wanderer() " `); - formatted = format(`void test() { printf("%O\n", animals["bird"].name); }`); + formatted = format( + `void test() { printf("%O\n", animals["bird"].name); }` + ); expect(formatted).toMatchSnapshot("indexor-member-exp"); }); @@ -860,13 +864,25 @@ move_wanderer() }); }); + describe("Default Arguments", () => { + test("Format functions with default closure arguments", () => { + let formatted = format(`test(int j, string s: (: 0 :)) { int i = j; }`); + expect(formatted).toMatchInlineSnapshot(` + "test(int j, string s: (: 0 :)) { int i = j; } + " + `); + }); + }); + test("handles the spread operator (FluffOS)", () => { let formatted = format( `mixed sum(mixed *numbers...) { mixed number, result = 0; fn(1, numbers...); return result; }` ); expect(formatted).toMatchSnapshot("spread-op-function-and-callexp"); - formatted = format(`debugf(sprintf("Alarm %O: %O called at %s", alarm.args..., ctime())) ;`); + formatted = format( + `debugf(sprintf("Alarm %O: %O called at %s", alarm.args..., ctime())) ;` + ); expect(formatted).toMatchSnapshot("spread-on-member-exp"); }); diff --git a/src/plugin/print/var.ts b/src/plugin/print/var.ts index 4b9d0b4..fb6f3f9 100644 --- a/src/plugin/print/var.ts +++ b/src/plugin/print/var.ts @@ -1,5 +1,6 @@ import { Doc, util } from "prettier"; import { builders } from "prettier/doc"; +import { ParameterDefaultValueNode } from "../../nodeTypes/functionDeclaration"; import { TypeCastExpressionNode } from "../../nodeTypes/typeCast"; import { VariableDeclarationNode, @@ -79,10 +80,16 @@ export const printVar: PrintNodeFunction< arr.push(lineSuffix([" ", path.call(printChildren, "suffixComments")])); } if (init) { - arr.push(" ="); - const shouldIndent = init.type != "array" && init.type != "mapping"; - const printedInit = path.call(printChildren, "init"); + + if (init instanceof ParameterDefaultValueNode) { + arr.push(":", group(indent([line, printedInit]))); + return arr; + } else { + arr.push(" ="); + } + + const shouldIndent = init.type != "array" && init.type != "mapping"; if (shouldIndent) { arr.push(group(indent([line, printedInit]))); } else { diff --git a/src/plugin/printer.ts b/src/plugin/printer.ts index bbeb749..f44427d 100644 --- a/src/plugin/printer.ts +++ b/src/plugin/printer.ts @@ -23,7 +23,7 @@ import { ForStatementNode, MultiExpressionNode, } from "../nodeTypes/forStatement"; -import { FunctionDeclarationNode } from "../nodeTypes/functionDeclaration"; +import { FunctionDeclarationNode, ParameterDefaultValueNode } from "../nodeTypes/functionDeclaration"; import { IdentifierNode } from "../nodeTypes/identifier"; import { IfNode } from "../nodeTypes/if"; import { InheritNode } from "../nodeTypes/inherit"; @@ -81,6 +81,7 @@ import { } from "./print/expression"; import { printFunction, + printParamDefaultValue, printParentExpression, printReturn, } from "./print/function"; @@ -296,6 +297,8 @@ const printNode: PrintNodeFunction = (node, ...commonPrintArgs) => { ); case "struct-literal": return printStructLiteral(node as StructLiteralNode, ...commonPrintArgs); + case "parameterDefaultValue": + return printParamDefaultValue(node as ParameterDefaultValueNode, ...commonPrintArgs); } return ["###Printer Unknown Node Type: " + node.type];