Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate TypeScript type definitions #1273

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
85b85bf
Basic parsing, far from complete
niklaskorz Feb 2, 2018
e99ebfc
Parse jsdoc comments with doctrine
niklaskorz Feb 2, 2018
723e1a5
Parse and filter relevant definitions
niklaskorz Feb 2, 2018
4dd5e96
Implement definition tree building
niklaskorz Feb 2, 2018
d1c8e80
Implement basic output generation
niklaskorz Feb 3, 2018
b4505b6
Generate output for instance methods and properties, constructor, add…
niklaskorz Feb 3, 2018
951806b
Remove newlines from doc comment descriptions while parsing
niklaskorz Feb 3, 2018
e6b3cf9
Split TypeScript definition generator into two modules, add support f…
niklaskorz Feb 3, 2018
402b8d8
Move definition tree building into separate module, support multiple …
niklaskorz Feb 3, 2018
02043db
Mark top-level namespaces as ambient
niklaskorz Feb 3, 2018
f4da9fa
Implement generation of interface nodes
niklaskorz Feb 3, 2018
c9a6242
Implement output generation for typedefs
niklaskorz Feb 3, 2018
a1a54fd
Fix output of `interface ... extends`
niklaskorz Feb 3, 2018
ea192a0
Include `extends` and `implements` keywords in class declaration
niklaskorz Feb 3, 2018
2d2b1ce
Move type generation to separate module, fix static class member aggr…
niklaskorz Feb 3, 2018
903257d
Add generateTypescriptDefinitions to python build script
niklaskorz Feb 3, 2018
c47d8bc
Allow externs declarations without doc comments
niklaskorz Feb 3, 2018
ee3c10f
Create default empty prototype for classes that only consist of a con…
niklaskorz Feb 3, 2018
913e84f
Save reference to implemented interface in class nodes when building …
niklaskorz Feb 3, 2018
691ddce
Remove obsolete comment
niklaskorz Feb 3, 2018
105f7fb
Infer class prop types from interface if no type is given
niklaskorz Feb 3, 2018
6455f9d
Mark optional parameters as optional in function node generation
niklaskorz Feb 3, 2018
6a5fa0d
Add types field to package.json
niklaskorz Feb 3, 2018
46d7d20
Move tree traversal utilities to treeUtils submodule
niklaskorz Feb 3, 2018
9a51b2d
Export functions in treeUtils module
niklaskorz Feb 3, 2018
ee66edc
Move interface lookup for class nodes from buildDefinitionTree to wri…
niklaskorz Feb 3, 2018
d3575be
Remove obsolete code from buildDefinitionTree
niklaskorz Feb 3, 2018
bb8f54c
Generate factory typedefs as interfaces
niklaskorz Feb 3, 2018
56b0aca
Fix indentation
niklaskorz Feb 3, 2018
5ecf242
Write constructor description comment before class declaration as well
niklaskorz Feb 3, 2018
8d18d6f
Comments are fine for now, remove TODO comment
niklaskorz Feb 3, 2018
1c72cde
Implement TS type generation
niklaskorz Feb 3, 2018
1121124
Correctly handle Object types with type applications as dictionary types
niklaskorz Feb 3, 2018
0421403
Wrap function types in parentheses
niklaskorz Feb 3, 2018
822d9fe
Fix generation of `new()` interfaces
niklaskorz Feb 3, 2018
abafd6e
Properly place ellipsis before rest parameters inside function nodes
niklaskorz Feb 3, 2018
7f80b53
Update type generation of arrays
niklaskorz Feb 3, 2018
34ac763
Throw errors instead of logging
niklaskorz Feb 3, 2018
fc8575b
Implement parsing and output for templates / generics
niklaskorz Feb 3, 2018
a6ad6a5
Fix enum nullability check in processType
niklaskorz Feb 4, 2018
a28fcdf
Fix primitive detection in processType
niklaskorz Feb 4, 2018
4644b22
Add option to disable nullability inference
niklaskorz Feb 4, 2018
af73703
Fix type inference for class properties
niklaskorz Feb 4, 2018
68c46b6
Infer nullability for unions and typedef types
niklaskorz Feb 4, 2018
225bf1b
Implement type inference for base interfaces
niklaskorz Feb 4, 2018
f7d53b3
Fix type inference for methods
niklaskorz Feb 4, 2018
5c09576
Fix type inference for const properties
niklaskorz Feb 4, 2018
f29a42d
Add tsconfig for validating generated type definitions
niklaskorz Feb 5, 2018
a6c4cb1
Move `writeLine` methods of Writer classes to abstract base class
niklaskorz Mar 18, 2018
e800ac1
Restructure parsing logic for building the definition tree
niklaskorz Mar 18, 2018
ce68df0
Fix typescript generation bugs
niklaskorz Mar 18, 2018
3c2b634
Merge branch 'master' of https://github.com/google/shaka-player into …
niklaskorz Nov 10, 2019
31a9c18
Apply shaka-player eslint rules
niklaskorz Nov 10, 2019
e025ddc
Replace console.assert with assert.strict
niklaskorz Nov 11, 2019
fe5e203
Use assert.equal where applicable
niklaskorz Nov 11, 2019
3b3ada2
Handle @namespace and generics in interfaces
niklaskorz Nov 11, 2019
46a6e6c
Begin adapting class parser for ES6 classes
niklaskorz Nov 11, 2019
65f32c1
Begin migration of ts type generator to typescript
niklaskorz Nov 12, 2019
99887b0
Ignore .vscode workspace
niklaskorz Nov 12, 2019
b1497fd
Progress on TypeScript conversion
niklaskorz Nov 13, 2019
d5aa805
Finish static typing of typing generator, next: adapt to recent shaka…
niklaskorz Nov 17, 2019
0221c00
Fix class and interface parsing
niklaskorz Nov 17, 2019
762b51b
Handle template arguments in interfaces
niklaskorz Nov 17, 2019
65bdd86
Fix interface method param and return type inference
niklaskorz Nov 17, 2019
8061643
Fix prop type lookup for interfaces
niklaskorz Nov 17, 2019
4d01048
Do not include constructors in interfaces
niklaskorz Nov 17, 2019
1e891ab
Begin adaptation to remaining externs
niklaskorz Nov 18, 2019
dfa7a5a
Make TypescriptGenerator work on Windows
niklaskorz Nov 18, 2019
26b695e
Handle "null" and "nullable" literals
niklaskorz Nov 18, 2019
185c21a
Fix varArgs parameters
niklaskorz Nov 18, 2019
8ba18a6
Move properties before constructor in output
niklaskorz Nov 18, 2019
a79550e
Warn about static properties without definition
niklaskorz Nov 18, 2019
00d3d1a
Treat base classes and interfaces as raw types instead of strings
niklaskorz Nov 18, 2019
af3b813
Default to any for template parameters
niklaskorz Nov 18, 2019
b511143
Mark all top level declarations as ambient
niklaskorz Nov 18, 2019
cc5774e
Deal with extension of global interfaces correctly
niklaskorz Nov 18, 2019
3e0eb02
Only include necessary externs
niklaskorz Nov 18, 2019
c435aee
Add predefined types and interfaces for inference and generation
niklaskorz Nov 20, 2019
5d603bc
Add base class inference for methods
niklaskorz Nov 20, 2019
43717ac
Remove base class type inference
niklaskorz Nov 20, 2019
67344fc
Correctly extend window.Error
niklaskorz Nov 20, 2019
505df00
Fix parsing interface externs that are defined with ES6 classes
niklaskorz Nov 20, 2019
ac6a713
Print comments before type aliases
niklaskorz Nov 20, 2019
bb22b26
Add module export statements to type definitions
niklaskorz Nov 21, 2019
00a0feb
Begin writing test files for typescript typings
niklaskorz Nov 21, 2019
0ebc0aa
Infer super class from class definition if no annotation is given
niklaskorz Nov 21, 2019
6154475
Provide type argument to super class of PendingRequest
niklaskorz Nov 21, 2019
c480fc1
Merge branch 'master' of https://github.com/google/shaka-player into …
niklaskorz Nov 23, 2019
536221b
Export Uint8ArrayUtils
niklaskorz Nov 23, 2019
ae83934
Update tsconfig for test files
niklaskorz Nov 25, 2019
5076f59
Call initApp()
niklaskorz Nov 25, 2019
808f596
Generate typings from source files instead of generated externs
niklaskorz Nov 25, 2019
dfbe7d1
Patch definitions
niklaskorz Nov 29, 2019
fc7a086
Export and patch UIConfiguration
niklaskorz Nov 29, 2019
72eb321
UI configuration
niklaskorz Nov 29, 2019
1c9f21b
Update ui ts test
niklaskorz Nov 29, 2019
3035af6
Parse and generate typings for events
niklaskorz Nov 30, 2019
323bce1
Update docs
niklaskorz Nov 30, 2019
5dcbfd5
Check typings after generation
niklaskorz Nov 30, 2019
0b124fa
Let all events extend the Event interface
niklaskorz Nov 30, 2019
ff95e1f
Explicitly mark unknown types as typescript "unknown" to make missing…
niklaskorz Nov 30, 2019
5febf1b
Fix type inference for properties defined in constructors
niklaskorz Nov 30, 2019
26e5e69
Fix test of typescript typings
niklaskorz Nov 30, 2019
4d4c21d
Export necessary ad-related methods
niklaskorz Nov 30, 2019
1eb0612
Add annotation @exportTypescript
niklaskorz Nov 30, 2019
233e39c
Revert to `@exportDoc` as unknown annotations are not allowed
niklaskorz Nov 30, 2019
df3828a
Merge branch 'master' of https://github.com/google/shaka-player into …
niklaskorz Nov 30, 2019
5e4d669
Patch Error class
niklaskorz Nov 30, 2019
f865a23
Handle undefiend in union return types
niklaskorz Nov 30, 2019
16c6137
Fix declaration of CueRegion.scroll property
niklaskorz Dec 1, 2019
46708eb
Update remove method signature of TextDisplayer implementations to ma…
niklaskorz Dec 1, 2019
8bd6f0c
Update method signature of predefined interface method EventTarget.re…
niklaskorz Dec 1, 2019
bad67af
Document base types
niklaskorz Dec 12, 2019
eb24c63
Fix parameter type inference
niklaskorz Dec 12, 2019
f08c433
Merge branch 'master' of https://github.com/google/shaka-player into …
niklaskorz Jan 18, 2020
cc6ff0f
Use `shakaBuildHelpers.get_node_binary`
niklaskorz Feb 12, 2020
f5c36a9
Revert change to eslintrc
niklaskorz Feb 12, 2020
d3af0eb
Add custom annotation `@exportTypescript`
niklaskorz Feb 12, 2020
31f192b
Use util.inspect instead of JSON.stringify for error messages
niklaskorz Feb 12, 2020
6093533
Detect and display errors in comment parser
niklaskorz Feb 12, 2020
c6b5f64
Log inspected tag in tag assertions
niklaskorz Feb 12, 2020
53a4525
Change tag error assertion
niklaskorz Feb 12, 2020
df0700b
Fix syntax errors in comments
niklaskorz Feb 12, 2020
65f6c38
Honor shaka's line length limit
niklaskorz Feb 12, 2020
0bdccfb
Merge remote-tracking branch 'upstream/master' into feature/generate-…
niklaskorz Apr 16, 2020
241c9ac
Fix errors
niklaskorz Apr 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ dist/
docs/api/
coverage/
.DS_Store
.vscode
8 changes: 8 additions & 0 deletions build/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import docs
import gendeps
import generateLocalizations
import logging
import shakaBuildHelpers

import os
Expand Down Expand Up @@ -143,6 +144,13 @@ def main(args):
is_debug = mode == 'debug'
if not apps.build_all(parsed_args.force, is_debug):
return 1

if 'release' in modes:
# Check if the generated Typescript typings are correct
logging.info('Checking generated Typescript typings...')
tsc = compiler.TypescriptCompiler("test/typescript/tsconfig.json")
if not tsc.compile():
return 1

return 0

Expand Down
5 changes: 5 additions & 0 deletions build/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
'--extra_annotation_name=listens',
'--extra_annotation_name=exportDoc',
'--extra_annotation_name=exportInterface',
'--extra_annotation_name=exportTypescript',

'--conformance_configs',
('%s/build/conformance.textproto' %
Expand Down Expand Up @@ -278,6 +279,7 @@ def build_library(self, name, locales, force, is_debug):
# Don't pass node modules to the extern generator.
local_include = set([f for f in self.include if 'node_modules' not in f])
generator = compiler.ExternGenerator(local_include, build_name)
ts_generator = compiler.TypescriptGenerator(local_include, build_name)

closure_opts = common_closure_opts + common_closure_defines
if is_debug:
Expand All @@ -290,6 +292,9 @@ def build_library(self, name, locales, force, is_debug):

if not generator.generate(force):
return False

if not ts_generator.generate(force):
return False

return True

Expand Down
55 changes: 55 additions & 0 deletions build/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,61 @@ def generate(self, force=False):
return True


class TypescriptGenerator(object):
def __init__(self, source_files, build_name):
self.source_files = _canonicalize_source_files(source_files)
self.output = _get_source_path('dist/' + build_name + '.d.ts')

def generate(self, force=False):
"""Generates TypeScript definitions for the files in |self.source_files|.

Args:
force: Generate the output even if the inputs have not changed.

Returns:
True on success; False on failure.
"""
if not force and not _must_build(self.output, self.source_files):
return True

ts_generator = _get_source_path('build/typescript/main.ts')
tsconfig = _get_source_path('build/typescript/tsconfig.json')

ts_node = shakaBuildHelpers.get_node_binary('ts-node')
ts_options = ['-P', tsconfig, ts_generator, '--output', self.output]

cmd_line = ts_node + ts_options + self.source_files

if shakaBuildHelpers.execute_get_code(cmd_line) != 0:
logging.error('TypeScript generation failed')
return False

return True


class TypescriptCompiler(object):
def __init__(self, project):
self.project = _get_source_path(project)

def compile(self):
"""Compiles the TypeScript project defined by the tsconfig in |self.project|.

Returns:
True on success; False on failure.
"""

tsc = shakaBuildHelpers.get_node_binary('typescript', 'tsc')
tsc_options = ['-p', self.project]
cmd_line = tsc + tsc_options

if shakaBuildHelpers.execute_get_code(cmd_line) != 0:
logging.error('TypeScript compiler failed')
return False

return True



class Less(object):
def __init__(self, main_source_file, all_source_files, output):
# Less only takes one input file, but that input may import others.
Expand Down
11 changes: 11 additions & 0 deletions build/typescript/assert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { strict } from "assert";

export const fail = strict.fail;

// Workaround for node.js "assert" module missing the new TypeScript "asserts" syntax
const assert: (
condition: unknown,
message?: string | Error
) => asserts condition = strict.ok;

export default assert;
159 changes: 159 additions & 0 deletions build/typescript/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import * as doctrine from "@teppeis/doctrine";

/**
* Type of "@" annotation in Closure block comment
*/
export enum AnnotationType {
Const = "const",
Enum = "enum",
Class = "class",
Interface = "interface",
Function = "function",
Property = "property",
Typedef = "typedef",
Namespace = "namespace",
Event = "event"
}

/**
* A property defined by the @property annotation
*/
export interface Props {
name: string;
type: doctrine.Type;
description?: string;
}

/**
* Metadata defined by annotations in closure block comment
*/
export interface Attributes {
type?: AnnotationType;
description?: string;
identifier?: string[];
comments: string[];
export: boolean;

props?: Props[];
constType?: doctrine.Type;
enumType?: doctrine.Type;
typedefType?: doctrine.Type;
propType?: doctrine.Type;
paramTypes?: doctrine.Type[];
returnType?: doctrine.Type;
eventType?: string; // Not a real type, but a string identifier

implements?: doctrine.Type;
extends?: doctrine.Type;
template?: string[];
}

/**
* Type of JS value assigned to the definition.
* Comment definitions are block comments that are not followed by a
* JS statement.
*/
export enum DefinitionType {
Function = "function",
Object = "object",
Class = "class",
Property = "property",
Comment = "comment"
}

/**
* Common definition properties
*/
export interface BaseDefinition {
identifier: string[];
attributes?: Attributes;
}

/**
* JavaScript function declarations
*/
export interface FunctionDefinition extends BaseDefinition {
type: DefinitionType.Function;
params: string[];

isMethod?: boolean;
isStatic?: boolean;
isConstructor?: boolean;
definitions?: Definition[];
}

/**
* JavaScript object literals
*/
export interface ObjectDefinition extends BaseDefinition {
type: DefinitionType.Object;
props: string[];
}

/**
* ES2015 class declarations
*/
export interface ClassDefinition extends BaseDefinition {
type: DefinitionType.Class;
superClass?: string[];
methods: FunctionDefinition[];
}

/**
* All other values or member expressions without assignment
*/
export interface PropertyDefinition extends BaseDefinition {
type: DefinitionType.Property;
}

/**
* Block comments without following JavaScript statement
*/
export interface CommentDefinition extends BaseDefinition {
type: DefinitionType.Comment;
}

/**
* Definitions parsed from the incoming Closure code
*/
export type Definition =
| FunctionDefinition
| ObjectDefinition
| ClassDefinition
| PropertyDefinition
| CommentDefinition;

/**
* Type for definition tree nodes
*/
export interface Node {
name: string;
definition?: Definition;
children: Map<string, Node>;
}

/**
* Base type used for building the definition tree
*/
export type NodeMap = Map<string, Node>;

/**
* Must be implemented by output targets for writing type definitions
*/
export interface Writer {
increaseLevel(): void;
decreaseLevel(): void;
getIndentation(): string;

write(str: string): void;
writeLine(str: string): void;
writeComments(comments: string[]): void;
writePrefix(): void;
}

/**
* Must be implemented by nodes that should be written to the output
*/
export interface Writable {
write(writer: Writer): void;
}
Loading