X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 13 additions & 36 deletions src/transformation/utils/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,7 @@ function createAnnotation(name: string, args: string[]): Annotation | undefined

export type AnnotationsMap = Map<AnnotationKind, Annotation>;

function collectAnnotations(
context: TransformationContext,
source: ts.Symbol | ts.Signature,
annotationsMap: AnnotationsMap
): void {
const comments = source.getDocumentationComment(context.checker);
const oldStyleAnnotations = comments
.filter(comment => comment.kind === "text")
.map(comment => comment.text.split("\n"))
.reduce((a, b) => a.concat(b), [])
.map(line => line.trim())
.filter(comment => comment[0] === "!");

for (const line of oldStyleAnnotations) {
const [name, ...args] = line.slice(1).split(" ");
const annotation = createAnnotation(name, args);
if (annotation) {
annotationsMap.set(annotation.kind, annotation);
console.warn(`[Deprecated] Annotations with ! are being deprecated, use '@${annotation.kind}' instead`);
} else {
console.warn(`Encountered unknown annotation '${line}'.`);
}
}

function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void {
for (const tag of source.getJsDocTags()) {
const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []);
if (annotation) {
Expand All @@ -65,17 +42,17 @@ function collectAnnotations(
}
}

export function getSymbolAnnotations(context: TransformationContext, symbol: ts.Symbol): AnnotationsMap {
export function getSymbolAnnotations(symbol: ts.Symbol): AnnotationsMap {
const annotationsMap: AnnotationsMap = new Map();
collectAnnotations(context, symbol, annotationsMap);
collectAnnotations(symbol, annotationsMap);
return annotationsMap;
}

export function getTypeAnnotations(context: TransformationContext, type: ts.Type): AnnotationsMap {
export function getTypeAnnotations(type: ts.Type): AnnotationsMap {
const annotationsMap: AnnotationsMap = new Map();

if (type.symbol) collectAnnotations(context, type.symbol, annotationsMap);
if (type.aliasSymbol) collectAnnotations(context, type.aliasSymbol, annotationsMap);
if (type.symbol) collectAnnotations(type.symbol, annotationsMap);
if (type.aliasSymbol) collectAnnotations(type.aliasSymbol, annotationsMap);

return annotationsMap;
}
Expand Down Expand Up @@ -116,14 +93,14 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap {

export function getSignatureAnnotations(context: TransformationContext, signature: ts.Signature): AnnotationsMap {
const annotationsMap: AnnotationsMap = new Map();
collectAnnotations(context, signature, annotationsMap);
collectAnnotations(signature, annotationsMap);

// Function properties on interfaces have the JSDoc tags on the parent PropertySignature
const declaration = signature.getDeclaration();
if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) {
const symbol = context.checker.getSymbolAtLocation(declaration.parent.name);
if (symbol) {
collectAnnotations(context, symbol, annotationsMap);
collectAnnotations(symbol, annotationsMap);
}
}

Expand Down Expand Up @@ -154,7 +131,7 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node)
}

const type = context.checker.getTypeAtLocation(node.expression);
return getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn);
return getTypeAnnotations(type).has(AnnotationKind.TupleReturn);
}

export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean {
Expand Down Expand Up @@ -185,20 +162,20 @@ export function isInTupleReturnFunction(context: TransformationContext, node: ts
return true;
}

return getTypeAnnotations(context, functionType).has(AnnotationKind.TupleReturn);
return getTypeAnnotations(functionType).has(AnnotationKind.TupleReturn);
}

export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean {
const type = context.checker.getTypeAtLocation(node);
return getTypeAnnotations(context, type).has(AnnotationKind.LuaIterator);
return getTypeAnnotations(type).has(AnnotationKind.LuaIterator);
}

export function isVarArgType(context: TransformationContext, node: ts.Node): boolean {
const type = context.checker.getTypeAtLocation(node);
return getTypeAnnotations(context, type).has(AnnotationKind.VarArg);
return getTypeAnnotations(type).has(AnnotationKind.VarArg);
}

export function isForRangeType(context: TransformationContext, node: ts.Node): boolean {
const type = context.checker.getTypeAtLocation(node);
return getTypeAnnotations(context, type).has(AnnotationKind.ForRange);
return getTypeAnnotations(type).has(AnnotationKind.ForRange);
}
2 changes: 1 addition & 1 deletion src/transformation/utils/assignment-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function validatePropertyAssignment(
if (!ts.isPropertyAccessExpression(node.left)) return;

const leftType = context.checker.getTypeAtLocation(node.left.expression);
const annotations = getTypeAnnotations(context, leftType);
const annotations = getTypeAnnotations(leftType);
if (annotations.has(AnnotationKind.LuaTable) && node.left.name.text === "length") {
throw ForbiddenLuaTableUseException(`A LuaTable object's length cannot be re-assigned.`, node);
}
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const transformPropertyAccessExpression: FunctionVisitor<ts.PropertyAcces
const property = expression.name.text;
const type = context.checker.getTypeAtLocation(expression.expression);

const annotations = getTypeAnnotations(context, type);
const annotations = getTypeAnnotations(type);
// Do not output path for member only enums
if (annotations.has(AnnotationKind.CompileMembersOnly)) {
if (ts.isPropertyAccessExpression(expression.expression)) {
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/binary-expression/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression> = (
const lhs = context.transformExpression(node.left);
const rhs = context.transformExpression(node.right);
const rhsType = context.checker.getTypeAtLocation(node.right);
const annotations = getTypeAnnotations(context, rhsType);
const annotations = getTypeAnnotations(rhsType);

if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) {
// Cannot use instanceof on extension classes
Expand Down
6 changes: 3 additions & 3 deletions src/transformation/visitors/class/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export function transformClassDeclaration(
throw MissingClassName(classDeclaration);
}

const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(classDeclaration));
const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration));

// Find out if this class is extension of existing class
const extensionDirective = annotations.get(AnnotationKind.Extension);
Expand All @@ -113,15 +113,15 @@ export function transformClassDeclaration(

if (!(isExtension || isMetaExtension) && extendsType) {
// Non-extensions cannot extend extension classes
const extendsAnnotations = getTypeAnnotations(context, extendsType);
const extendsAnnotations = getTypeAnnotations(extendsType);
if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) {
throw InvalidExtendsExtension(classDeclaration);
}
}

// You cannot extend LuaTable classes
if (extendsType) {
const annotations = getTypeAnnotations(context, extendsType);
const annotations = getTypeAnnotations(extendsType);
if (annotations.has(AnnotationKind.LuaTable)) {
throw InvalidExtendsLuaTable(classDeclaration);
}
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/class/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const transformNewExpression: FunctionVisitor<ts.NewExpression> = (node,

checkForLuaLibType(context, type);

const annotations = getTypeAnnotations(context, type);
const annotations = getTypeAnnotations(type);

if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) {
throw InvalidNewExpressionOnExtension(node);
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/class/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function getExtendedTypeNode(
for (const clause of node.heritageClauses) {
if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
const superType = context.checker.getTypeAtLocation(clause.types[0]);
const annotations = getTypeAnnotations(context, superType);
const annotations = getTypeAnnotations(superType);
if (!annotations.has(AnnotationKind.PureAbstract)) {
return clause.types[0];
}
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const transformEnumDeclaration: FunctionVisitor<ts.EnumDeclaration> = (no
}

const type = context.checker.getTypeAtLocation(node);
const membersOnly = getTypeAnnotations(context, type).has(AnnotationKind.CompileMembersOnly);
const membersOnly = getTypeAnnotations(type).has(AnnotationKind.CompileMembersOnly);
const result: lua.Statement[] = [];

if (!membersOnly) {
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/loops/for-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function transformForOfLuaIteratorStatement(
): lua.Statement {
const luaIterator = context.transformExpression(statement.expression);
const type = context.checker.getTypeAtLocation(statement.expression);
const tupleReturn = getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn);
const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn);
if (tupleReturn) {
// LuaIterator + TupleReturn
if (ts.isVariableDeclarationList(statement.initializer)) {
Expand Down
10 changes: 5 additions & 5 deletions src/transformation/visitors/lua-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function transformLuaTableExpressionStatement(

if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) {
const ownerType = context.checker.getTypeAtLocation(expression.expression.expression);
const annotations = getTypeAnnotations(context, ownerType);
const annotations = getTypeAnnotations(ownerType);
if (annotations.has(AnnotationKind.LuaTable)) {
return transformLuaTableExpressionAsExpressionStatement(context, expression);
}
Expand All @@ -84,7 +84,7 @@ export function transformLuaTableCallExpression(
): lua.Expression | undefined {
if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) {
const ownerType = context.checker.getTypeAtLocation(node.expression.expression);
const annotations = getTypeAnnotations(context, ownerType);
const annotations = getTypeAnnotations(ownerType);

if (annotations.has(AnnotationKind.LuaTable)) {
const [luaTable, methodName] = parseLuaTableExpression(context, node.expression);
Expand All @@ -107,7 +107,7 @@ export function transformLuaTablePropertyAccessExpression(
node: ts.PropertyAccessExpression
): lua.Expression | undefined {
const type = context.checker.getTypeAtLocation(node.expression);
const annotations = getTypeAnnotations(context, type);
const annotations = getTypeAnnotations(type);
if (annotations.has(AnnotationKind.LuaTable)) {
const [luaTable, propertyName] = parseLuaTableExpression(context, node);
switch (node.name.text) {
Expand All @@ -123,7 +123,7 @@ export function transformLuaTableElementAccessExpression(
context: TransformationContext,
node: ts.ElementAccessExpression
): void {
const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node.expression));
const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression));
if (annotations.has(AnnotationKind.LuaTable)) {
throw UnsupportedKind("LuaTable access expression", node.kind, node);
}
Expand All @@ -134,7 +134,7 @@ export function transformLuaTableNewExpression(
node: ts.NewExpression
): lua.Expression | undefined {
const type = context.checker.getTypeAtLocation(node);
const annotations = getTypeAnnotations(context, type);
const annotations = getTypeAnnotations(type);
if (annotations.has(AnnotationKind.LuaTable)) {
if (node.arguments && node.arguments.length > 0) {
throw ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", node);
Expand Down
4 changes: 2 additions & 2 deletions src/transformation/visitors/modules/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function shouldResolveModulePath(context: TransformationContext, moduleSpecifier
const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier);
if (!moduleOwnerSymbol) return true;

const annotations = getSymbolAnnotations(context, moduleOwnerSymbol);
const annotations = getSymbolAnnotations(moduleOwnerSymbol);
return !annotations.has(AnnotationKind.NoResolution);
}

Expand All @@ -66,7 +66,7 @@ export function createModuleRequire(
}

function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean {
const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(importNode));
const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(importNode));

return (
context.resolver.isReferencedAliasDeclaration(importNode) &&
Expand Down
2 changes: 1 addition & 1 deletion src/transformation/visitors/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function moduleHasEmittedBody(
const currentNamespaces = new WeakMap<TransformationContext, ts.ModuleDeclaration | undefined>();

export const transformModuleDeclaration: FunctionVisitor<ts.ModuleDeclaration> = (node, context) => {
const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node));
const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node));
// If phantom namespace elide the declaration and return the body
if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) {
return context.transformStatements(node.body.statements);
Expand Down
X Tutup