Skip to content

Commit

Permalink
Wollokdoc enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
fdodino committed Dec 5, 2024
1 parent a6954ea commit 857d1ee
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 42 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"react": "^18.3.1",
"sharp": "^0.32.5",
"typescript": "^5.3.3",
"wollok-ts": "4.1.8",
"wollok-ts": "4.1.9",
"wollok-web-tools": "1.1.5"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/content/components/language/WollokDoc.astro
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const codeThemes = [
.split("\n") // Same format than the code
.map((text) => <p style="margin-top:0;" set:html={sanitize(text)} />)
) : (
<p style="margin-top:0;">No documentation available</p>
<p style="margin-top:0;"></p>
)
}
{
Expand Down
87 changes: 47 additions & 40 deletions src/content/components/language/utils.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Class, Entity, Field, Method, Mixin, Node, Package, Singleton, buildEnvironment } from 'wollok-ts'
import { last, match, when, type List } from 'wollok-ts'
import { Annotation, Class, Entity, Field, Method, Mixin, Node, Package, Singleton, buildEnvironment, last } from 'wollok-ts'
import { match, when, type List } from 'wollok-ts'

const expectedSort = ['lang', 'lib', 'game' /* ... and the rest */]
function sortPackages() {
const packages = buildEnvironment([]).getNodeByFQN<Package>('wollok').members as Package[]
// Next line has effect
packages.sort((p1, p2) => {
if (!expectedSort.includes(p1.name)) return 999
if (!expectedSort.includes(p2.name)) return -1
return expectedSort.indexOf(p1.name) - expectedSort.indexOf(p2.name)
})
return packages
const packages = buildEnvironment([]).getNodeByFQN<Package>('wollok').members as Package[]
// Next line has effect
packages.sort((p1, p2) => {
if (!expectedSort.includes(p1.name)) return 999
if (!expectedSort.includes(p2.name)) return -1
return expectedSort.indexOf(p1.name) - expectedSort.indexOf(p2.name)
})
return packages
}

export const wollokPackages = sortPackages()

const wollokEntitiesRelevantMembers = (entity: Entity): List<Field|Method> => (match(entity)(
const wollokEntitiesRelevantMembers = (entity: Entity): List<Field | Method> => (match(entity)(
when(Singleton)(singleton => singleton.members),
when(Class)(klass => klass.members),
when(Mixin)(mixin => mixin.members),
when(Node)(_ => [])
) as List<Field|Method>).filter(node => !node.isSynthetic)
) as List<Field | Method>).filter(node => !node.isSynthetic)

export const wollokHeadings = wollokPackages.flatMap(pkg => ([
buildHeading(2)(pkg),
Expand All @@ -40,41 +40,48 @@ export function identifier(node: Package | Entity | Field | Method): string {
}

function buildHeading(depth: number): (node: Package | Entity | Field | Method) => { depth: number, slug: string, text: string } {
return (node) => ({
depth,
slug: identifier(node),
text: node.name ?? identifier(node),
})
return (node) => ({
depth,
slug: identifier(node),
text: node.name ?? identifier(node),
})
}

export function methodLabel(method: Method) {
return `${method.name}(${method.parameters.map(param => param.name).join(', ')})`
return `${method.name}(${method.parameters.map(param => param.name).join(', ')})`
}

export function wollokDoc(node: Node): string {
const comment = commentMetadataFor(node)
return comment?.args['text'] as string ?? '<i>Documentation not found</i>'
const comment = commentMetadataFor(node)
return comment?.args['text'] as string ?? ''
}

function commentMetadataFor(node: Node) {
const inlinedReturn = (method: Method): Node => {
const lastSentence = last(method.sentences)!
return lastSentence?.descendants?.find(_ => _.metadata.length > 0) ?? method
}
// Solves bug on parsing start/end comments
const index = node.parent.children.indexOf(node)
// First child has its comment as 'start'
if (index == 0) return node.metadata.find(_ => _.name == 'comment' && _.args['position'] == 'start')
// Next children have their comment as 'end' of the before
const before = node.parent.children[index - 1]
const commentedNode = match(before)<Node, any>(
when(Method)(method => !method.isConcrete()
? method
: (method.body.metadata.length > 0
? method.body
: inlinedReturn(method))),
when(Field)(field => field.value.isSynthetic ? field : field.value),
when(Node)(_ => _)
)
return commentedNode?.metadata.find(_ => _.name == 'comment' && _.args['position'] == 'end')
// Solves bug on parsing start/end comments
const getPreviousSiblingMetadata = (method: Method): Annotation | undefined => {
const siblingIndex = method.parent.methods.indexOf(method) - 1
const siblingMethod = method.parent.methods[siblingIndex]
if (!siblingMethod) return undefined
const lastSentence = last(siblingMethod.sentences)!
const childWithMetadata = lastSentence?.descendants?.find(_ => _.metadata.length)
return childWithMetadata ? getMetadata(childWithMetadata) : siblingMethod.metadata[1] ?? siblingMethod.metadata[0]
}

const getMetadata = (node: Node) => node.metadata.find(({ name, args }: Annotation) => name == 'comment' && (args['position'] == 'start' || (args['position'] == 'end' && !node.is(Method))))

const getMetadataForNode = (node: Node) => {
const parent = node.parent
const siblingIndex = parent.children.indexOf(node) - 1
const siblingNode = parent.children[siblingIndex]
const metadata = siblingNode?.metadata.find(({ name, args }: Annotation) => name == 'comment' && args['position'] == 'end')
return metadata ?? getMetadata(node)
}

return match(node)<Annotation | undefined, any>(
when(Method)(method => getMetadata(method) ?? getPreviousSiblingMetadata(method)),
when(Field)(getMetadataForNode),
when(Class)(getMetadataForNode),
when(Singleton)(getMetadataForNode),
when(Node)(_ => getMetadata(_))
)
}

0 comments on commit 857d1ee

Please sign in to comment.