|
1 | 1 | import * as ts from "typescript"; |
2 | | -import { flatMap } from "../../../utils"; |
3 | | -import { TransformationContext } from "../../context"; |
| 2 | +import { flatMap } from "../../utils"; |
| 3 | +import { TransformationContext } from "../context"; |
| 4 | +import { findFirstNodeAbove, inferAssignedType } from "./typescript"; |
4 | 5 |
|
5 | 6 | export enum AnnotationKind { |
6 | 7 | Extension = "extension", |
@@ -129,3 +130,76 @@ export function getSignatureAnnotations(context: TransformationContext, signatur |
129 | 130 |
|
130 | 131 | return annotationsMap; |
131 | 132 | } |
| 133 | + |
| 134 | +export function isTupleReturnCall(context: TransformationContext, node: ts.Node): boolean { |
| 135 | + if (!ts.isCallExpression(node)) { |
| 136 | + return false; |
| 137 | + } |
| 138 | + |
| 139 | + const signature = context.checker.getResolvedSignature(node); |
| 140 | + if (signature) { |
| 141 | + if (getSignatureAnnotations(context, signature).has(AnnotationKind.TupleReturn)) { |
| 142 | + return true; |
| 143 | + } |
| 144 | + |
| 145 | + // Only check function type for directive if it is declared as an interface or type alias |
| 146 | + const declaration = signature.getDeclaration(); |
| 147 | + const isInterfaceOrAlias = |
| 148 | + declaration && |
| 149 | + declaration.parent && |
| 150 | + ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || |
| 151 | + ts.isTypeAliasDeclaration(declaration.parent)); |
| 152 | + if (!isInterfaceOrAlias) { |
| 153 | + return false; |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + const type = context.checker.getTypeAtLocation(node.expression); |
| 158 | + return getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn); |
| 159 | +} |
| 160 | + |
| 161 | +export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { |
| 162 | + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); |
| 163 | + if (!declaration) { |
| 164 | + return false; |
| 165 | + } |
| 166 | + |
| 167 | + let functionType: ts.Type | undefined; |
| 168 | + if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { |
| 169 | + functionType = inferAssignedType(context, declaration); |
| 170 | + } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { |
| 171 | + // Manually lookup type for object literal properties declared with method syntax |
| 172 | + const interfaceType = inferAssignedType(context, declaration.parent); |
| 173 | + const propertySymbol = interfaceType.getProperty(declaration.name.getText()); |
| 174 | + if (propertySymbol) { |
| 175 | + functionType = context.checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + if (functionType === undefined) { |
| 180 | + functionType = context.checker.getTypeAtLocation(declaration); |
| 181 | + } |
| 182 | + |
| 183 | + // Check all overloads for directive |
| 184 | + const signatures = functionType.getCallSignatures(); |
| 185 | + if (signatures && signatures.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { |
| 186 | + return true; |
| 187 | + } |
| 188 | + |
| 189 | + return getTypeAnnotations(context, functionType).has(AnnotationKind.TupleReturn); |
| 190 | +} |
| 191 | + |
| 192 | +export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { |
| 193 | + const type = context.checker.getTypeAtLocation(node); |
| 194 | + return getTypeAnnotations(context, type).has(AnnotationKind.LuaIterator); |
| 195 | +} |
| 196 | + |
| 197 | +export function isVarArgType(context: TransformationContext, node: ts.Node): boolean { |
| 198 | + const type = context.checker.getTypeAtLocation(node); |
| 199 | + return getTypeAnnotations(context, type).has(AnnotationKind.VarArg); |
| 200 | +} |
| 201 | + |
| 202 | +export function isForRangeType(context: TransformationContext, node: ts.Node): boolean { |
| 203 | + const type = context.checker.getTypeAtLocation(node); |
| 204 | + return getTypeAnnotations(context, type).has(AnnotationKind.ForRange); |
| 205 | +} |
0 commit comments