Skip to content

Commit

Permalink
Handle complicated expressions in initializer list
Browse files Browse the repository at this point in the history
  • Loading branch information
FirentisTFW committed Nov 16, 2024
1 parent 390b65f commit e35039a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 26 deletions.
33 changes: 33 additions & 0 deletions src/test/dart_class_parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,39 @@ describe("parseLinesToConstructors", () => {
),
]);
});

test("with complicated expressions in initializer list", () => {
const lines = [
" Loader.small(",
" this.active, {",
" super.key,",
" bool big = false,",
" required bool animated,",
" }) : semanticsLabel = List.filled(40, '*').join()",
];
const classFields = [
new DartClassField("active", "bool"),
new DartClassField("semanticsLabel", "String"),
new DartClassField("text", "String"),
new DartClassField("icon", "IconData"),
];

expect(parseLinesToConstructors(lines, "Loader", classFields)).toEqual([
new DartClassConstructor(
true,
[
new DartClassConstructorField(
"active",
"bool",
DartClassConstructorFieldPositionType.positional
),
new DartClassConstructorField("big", "bool"),
new DartClassConstructorField("animated", "bool"),
],
"small"
),
]);
});
});

describe("factory constructor", () => {
Expand Down
79 changes: 53 additions & 26 deletions src/util/dart_class_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ function parseLinesToConstructors(
for (let j = i; j < lines.length; j++) {
for (const char of lines[j]) {
if (char === "(") openParenthesisCount++;
else if (char === ")") openParenthesisCount--;
else if (char === ")") {
openParenthesisCount--;
// Exit as soon as the initial parenthesis block is closed.
if (openParenthesisCount == 0) break;
}
}
if (openParenthesisCount > 0 && !lines[j].includes("assert(")) {
continue;
Expand Down Expand Up @@ -165,8 +169,22 @@ function parseLinesToConstructor(
): DartClassConstructor | null {
if (!lines.length) return null;
const classFieldReference = "this.";
let namedParametersStartIndex = lines.findIndex((line) => line.includes("{"));
if (namedParametersStartIndex === -1) {
// No named params. Set to infinity for the check for positionType below.
namedParametersStartIndex = Infinity;
} else {
// Index will change after we pop name line below.
namedParametersStartIndex--;
}

const nameLine = lines.shift() as string;

if (lines.length > 0) {
// Remove constructor ending. No field would be defined in this line.
lines.pop();
}

const named = nameLine.includes(`${className}.`);
const constructorName = named
? nameLine.substring(nameLine.indexOf(".") + 1, nameLine.indexOf("("))
Expand All @@ -177,14 +195,16 @@ function parseLinesToConstructor(
.split(",")
// TODO Modify the line below when adding support for one-line constructors
.filter((line) => line !== "" && !line.includes("})"));
const namedParametersStartIndex = fieldsLines.findIndex((line) =>
line.includes("{")
);

const fields = fieldsLines
.map((line) => {
// Check some possible cases that would discard this line as one representing a field.
if (line.includes("super.") || line.includes(") {")) return null;
if (
line.includes("super.") ||
line.includes(") {") ||
line.includes("})")
)
return null;

const positionType =
fieldsLines.indexOf(line) > namedParametersStartIndex
Expand All @@ -193,27 +213,7 @@ function parseLinesToConstructor(
const custom = !line.includes(classFieldReference);

if (custom) {
const lineParts = line.trim().split(" ");
let name: string;
let type: string;
if (lineParts[0] === "required") {
name = lineParts[2];
type = lineParts[1];
} else {
name = lineParts[1];
type = lineParts[0];
}

if (type.endsWith("?")) {
return new DartClassConstructorField(
name,
type.removeTrailing(1),
positionType,
true
);
}

return new DartClassConstructorField(name, type, positionType, false);
return getCustomConstructorField(line, positionType);
} else {
const fieldName = getClassFieldName(line, classFieldReference);
const classField = allClassFields.find(
Expand All @@ -236,6 +236,33 @@ function parseLinesToConstructor(
);
}

function getCustomConstructorField(
line: string,
positionType: DartClassConstructorFieldPositionType
): DartClassConstructorField {
const lineParts = line.trim().split(" ");
let name: string;
let type: string;
if (lineParts[0] === "required") {
name = lineParts[2];
type = lineParts[1];
} else {
name = lineParts[1];
type = lineParts[0];
}

if (type.endsWith("?")) {
return new DartClassConstructorField(
name,
type.removeTrailing(1),
positionType,
true
);
}

return new DartClassConstructorField(name, type, positionType, false);
}

function classFieldToConstructorField(
classField: DartClassField,
positionType: DartClassConstructorFieldPositionType
Expand Down

0 comments on commit e35039a

Please sign in to comment.