Skip to content

Commit

Permalink
1401 add support for local module importexport to source typed (#1686)
Browse files Browse the repository at this point in the history
* add typechecking for export statement in typeErrorChecker

* merge

* update estree and TypedES

* Fix broken submodule changes

* Fix format

---------

Co-authored-by: Richard Dominick <[email protected]>
Co-authored-by: Martin Henz <[email protected]>
  • Loading branch information
3 people authored Apr 27, 2024
1 parent 8716791 commit 06d7f04
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@commander-js/extra-typings": "^12.0.1",
"@joeychenofficial/alt-ergo-modified": "^2.4.0",
"@ts-morph/bootstrap": "^0.18.0",
"@types/estree": "0.0.52",
"@types/estree": "^1.0.5",
"acorn": "^8.8.2",
"acorn-class-fields": "^1.0.0",
"acorn-loose": "^8.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/modules/preprocessor/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type es from 'estree'
// import * as TypedES from '../../typeChecker/tsESTree'

import type { Context, IOptions } from '../..'
import type { RecursivePartial } from '../../types'
Expand Down
2 changes: 1 addition & 1 deletion src/modules/preprocessor/transformers/removeExports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function removeExports(program: es.Program): void {
// it with the declaration node in its parent node's body.
return node.declaration.type === 'FunctionDeclaration' ||
node.declaration.type === 'ClassDeclaration'
? node.declaration
? (node.declaration as es.FunctionDeclaration)
: undefined
case 'ExportNamedDeclaration':
// If the ExportNamedDeclaration node contains a declaration, replace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ const getDefaultExportExpression = (
nodes: es.ModuleDeclaration[],
exportedNameToIdentifierMap: Partial<Record<string, es.Identifier>>
): es.Expression | null => {
let defaultExport: es.Expression | null = null
let defaultExport:
| es.MaybeNamedFunctionDeclaration
| es.MaybeNamedClassDeclaration
| es.Expression
| null = null

// Handle default exports which are parsed as ExportNamedDeclaration AST nodes.
// 'export { name as default };' is equivalent to 'export default name;' but
Expand All @@ -164,7 +168,6 @@ const getDefaultExportExpression = (
// This should never occur because multiple default exports should have
// been caught by the Acorn parser when parsing into an AST.
assert(defaultExport === null, 'Encountered multiple default exports!')

if (isDeclaration(node.declaration)) {
const identifier = getIdentifier(node.declaration)
if (identifier === null) {
Expand Down
25 changes: 21 additions & 4 deletions src/typeChecker/tsESTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface BaseNodeWithoutComments {
// The type property should be a string literal. For example, Identifier
// has: `type: "Identifier"`
type: string
loc?: es.SourceLocation | null | undefined
loc?: SourceLocation | null | undefined
range?: [number, number] | undefined
}

Expand Down Expand Up @@ -49,6 +49,12 @@ export interface Comment extends BaseNodeWithoutComments {
value: string
}

export interface SourceLocation {
source?: string | null | undefined
start: Position
end: Position
}

export interface Position {
/** >= 1 */
line: number
Expand Down Expand Up @@ -217,7 +223,7 @@ export type Declaration = FunctionDeclaration | VariableDeclaration | ClassDecla

type BaseDeclaration = BaseStatement

export interface FunctionDeclaration extends BaseFunction, BaseDeclaration {
export interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration {
type: 'FunctionDeclaration'
/** It is null when a function declaration is a part of the `export default function` statement */
id: Identifier | null
Expand All @@ -226,6 +232,10 @@ export interface FunctionDeclaration extends BaseFunction, BaseDeclaration {
returnType?: TSTypeAnnotation
}

export interface FunctionDeclaration extends MaybeNamedFunctionDeclaration {
id: Identifier
}

export interface VariableDeclaration extends BaseDeclaration {
type: 'VariableDeclaration'
declarations: Array<VariableDeclarator>
Expand Down Expand Up @@ -486,6 +496,9 @@ export type AssignmentOperator =
| '|='
| '^='
| '&='
| '||='
| '&&='
| '??='

export type UpdateOperator = '++' | '--'

Expand Down Expand Up @@ -588,12 +601,16 @@ export interface MethodDefinition extends BaseNode {
static: boolean
}

export interface ClassDeclaration extends BaseClass, BaseDeclaration {
export interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration {
type: 'ClassDeclaration'
/** It is null when a class declaration is a part of the `export default class` statement */
id: Identifier | null
}

export interface ClassDeclaration extends MaybeNamedClassDeclaration {
id: Identifier
}

export interface ClassExpression extends BaseClass, BaseExpression {
type: 'ClassExpression'
id?: Identifier | null | undefined
Expand Down Expand Up @@ -659,7 +676,7 @@ export interface ExportSpecifier extends BaseModuleSpecifier {

export interface ExportDefaultDeclaration extends BaseModuleDeclaration {
type: 'ExportDefaultDeclaration'
declaration: Declaration | Expression
declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression
}

export interface ExportAllDeclaration extends BaseModuleDeclaration {
Expand Down
2 changes: 2 additions & 0 deletions src/typeChecker/typeErrorChecker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,8 @@ function typeCheckAndReturnType(node: tsEs.Node): Type {
return typeToCastTo
case 'TSInterfaceDeclaration':
throw new TypecheckError(node, 'Interface declarations are not allowed')
case 'ExportNamedDeclaration':
return typeCheckAndReturnType(node.declaration!)
default:
throw new TypecheckError(node, 'Unknown node type')
}
Expand Down
6 changes: 5 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,11 @@ export interface StatementSequence extends es.BaseStatement {
/**
* js-slang's custom Node type - this should be used wherever es.Node is used.
*/
export type Node = es.Node | StatementSequence
export type Node =
| es.Node
| StatementSequence
| es.MaybeNamedClassDeclaration
| es.MaybeNamedFunctionDeclaration

/*
Although the ESTree specifications supposedly provide a Directive interface, the index file does not seem to export it.
Expand Down
2 changes: 1 addition & 1 deletion src/utils/ast/astCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export const functionDeclarationExpression = (
})

export const functionDeclaration = (
id: es.Identifier | null,
id: es.Identifier,
params: es.Pattern[],
body: es.BlockStatement,
loc?: es.SourceLocation | null
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1459,10 +1459,10 @@
dependencies:
"@babel/types" "^7.20.7"

"@types/estree@0.0.52":
version "0.0.52"
resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.52.tgz"
integrity sha512-BZWrtCU0bMVAIliIV+HJO1f1PR41M7NKjfxrFJwwhKI1KwhwOxYw1SXg9ao+CIMt774nFuGiG6eU+udtbEI9oQ==
"@types/estree@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==

"@types/graceful-fs@^4.1.3":
version "4.1.9"
Expand Down

0 comments on commit 06d7f04

Please sign in to comment.