|
1 | 1 | import * as ts from "typescript"; |
2 | | -import * as path from "path"; |
| 2 | +import { TransformationContext } from "../context"; |
3 | 3 |
|
4 | 4 | export enum ExtensionKind { |
5 | 5 | MultiFunction = "MultiFunction", |
6 | 6 | MultiType = "MultiType", |
7 | 7 | RangeFunction = "RangeFunction", |
| 8 | + IterableType = "IterableType", |
8 | 9 | AdditionOperatorType = "AdditionOperatorType", |
9 | 10 | AdditionOperatorMethodType = "AdditionOperatorMethodType", |
10 | 11 | SubtractionOperatorType = "SubtractionOperatorType", |
@@ -43,74 +44,66 @@ export enum ExtensionKind { |
43 | 44 | LengthOperatorMethodType = "LengthOperatorMethodType", |
44 | 45 | } |
45 | 46 |
|
46 | | -const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { |
47 | | - $multi: ExtensionKind.MultiFunction, |
48 | | - $range: ExtensionKind.RangeFunction, |
| 47 | +const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { |
| 48 | + [ExtensionKind.MultiFunction]: "$multi", |
| 49 | + [ExtensionKind.RangeFunction]: "$range", |
49 | 50 | }; |
50 | 51 |
|
51 | | -const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { |
52 | | - LuaMultiReturn: ExtensionKind.MultiType, |
53 | | - LuaAddition: ExtensionKind.AdditionOperatorType, |
54 | | - LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, |
55 | | - LuaSubtraction: ExtensionKind.SubtractionOperatorType, |
56 | | - LuaSubtractionMethod: ExtensionKind.SubtractionOperatorMethodType, |
57 | | - LuaMultiplication: ExtensionKind.MultiplicationOperatorType, |
58 | | - LuaMultiplicationMethod: ExtensionKind.MultiplicationOperatorMethodType, |
59 | | - LuaDivision: ExtensionKind.DivisionOperatorType, |
60 | | - LuaDivisionMethod: ExtensionKind.DivisionOperatorMethodType, |
61 | | - LuaModulo: ExtensionKind.ModuloOperatorType, |
62 | | - LuaModuloMethod: ExtensionKind.ModuloOperatorMethodType, |
63 | | - LuaPower: ExtensionKind.PowerOperatorType, |
64 | | - LuaPowerMethod: ExtensionKind.PowerOperatorMethodType, |
65 | | - LuaFloorDivision: ExtensionKind.FloorDivisionOperatorType, |
66 | | - LuaFloorDivisionMethod: ExtensionKind.FloorDivisionOperatorMethodType, |
67 | | - LuaBitwiseAnd: ExtensionKind.BitwiseAndOperatorType, |
68 | | - LuaBitwiseAndMethod: ExtensionKind.BitwiseAndOperatorMethodType, |
69 | | - LuaBitwiseOr: ExtensionKind.BitwiseOrOperatorType, |
70 | | - LuaBitwiseOrMethod: ExtensionKind.BitwiseOrOperatorMethodType, |
71 | | - LuaBitwiseExclusiveOr: ExtensionKind.BitwiseExclusiveOrOperatorType, |
72 | | - LuaBitwiseExclusiveOrMethod: ExtensionKind.BitwiseExclusiveOrOperatorMethodType, |
73 | | - LuaBitwiseLeftShift: ExtensionKind.BitwiseLeftShiftOperatorType, |
74 | | - LuaBitwiseLeftShiftMethod: ExtensionKind.BitwiseLeftShiftOperatorMethodType, |
75 | | - LuaBitwiseRightShift: ExtensionKind.BitwiseRightShiftOperatorType, |
76 | | - LuaBitwiseRightShiftMethod: ExtensionKind.BitwiseRightShiftOperatorMethodType, |
77 | | - LuaConcat: ExtensionKind.ConcatOperatorType, |
78 | | - LuaConcatMethod: ExtensionKind.ConcatOperatorMethodType, |
79 | | - LuaLessThan: ExtensionKind.LessThanOperatorType, |
80 | | - LuaLessThanMethod: ExtensionKind.LessThanOperatorMethodType, |
81 | | - LuaGreaterThan: ExtensionKind.GreaterThanOperatorType, |
82 | | - LuaGreaterThanMethod: ExtensionKind.GreaterThanOperatorMethodType, |
83 | | - LuaNegation: ExtensionKind.NegationOperatorType, |
84 | | - LuaNegationMethod: ExtensionKind.NegationOperatorMethodType, |
85 | | - LuaBitwiseNot: ExtensionKind.BitwiseNotOperatorType, |
86 | | - LuaBitwiseNotMethod: ExtensionKind.BitwiseNotOperatorMethodType, |
87 | | - LuaLength: ExtensionKind.LengthOperatorType, |
88 | | - LuaLengthMethod: ExtensionKind.LengthOperatorMethodType, |
| 52 | +const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { |
| 53 | + [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", |
| 54 | + [ExtensionKind.MultiType]: "__luaMultiReturnBrand", |
| 55 | + [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", |
| 56 | + [ExtensionKind.IterableType]: "__luaIterableBrand", |
| 57 | + [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", |
| 58 | + [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", |
| 59 | + [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", |
| 60 | + [ExtensionKind.SubtractionOperatorMethodType]: "__luaSubtractionMethodBrand", |
| 61 | + [ExtensionKind.MultiplicationOperatorType]: "__luaMultiplicationBrand", |
| 62 | + [ExtensionKind.MultiplicationOperatorMethodType]: "__luaMultiplicationMethodBrand", |
| 63 | + [ExtensionKind.DivisionOperatorType]: "__luaDivisionBrand", |
| 64 | + [ExtensionKind.DivisionOperatorMethodType]: "__luaDivisionMethodBrand", |
| 65 | + [ExtensionKind.ModuloOperatorType]: "__luaModuloBrand", |
| 66 | + [ExtensionKind.ModuloOperatorMethodType]: "__luaModuloMethodBrand", |
| 67 | + [ExtensionKind.PowerOperatorType]: "__luaPowerBrand", |
| 68 | + [ExtensionKind.PowerOperatorMethodType]: "__luaPowerMethodBrand", |
| 69 | + [ExtensionKind.FloorDivisionOperatorType]: "__luaFloorDivisionBrand", |
| 70 | + [ExtensionKind.FloorDivisionOperatorMethodType]: "__luaFloorDivisionMethodBrand", |
| 71 | + [ExtensionKind.BitwiseAndOperatorType]: "__luaBitwiseAndBrand", |
| 72 | + [ExtensionKind.BitwiseAndOperatorMethodType]: "__luaBitwiseAndMethodBrand", |
| 73 | + [ExtensionKind.BitwiseOrOperatorType]: "__luaBitwiseOrBrand", |
| 74 | + [ExtensionKind.BitwiseOrOperatorMethodType]: "__luaBitwiseOrMethodBrand", |
| 75 | + [ExtensionKind.BitwiseExclusiveOrOperatorType]: "__luaBitwiseExclusiveOrBrand", |
| 76 | + [ExtensionKind.BitwiseExclusiveOrOperatorMethodType]: "__luaBitwiseExclusiveOrMethodBrand", |
| 77 | + [ExtensionKind.BitwiseLeftShiftOperatorType]: "__luaBitwiseLeftShiftBrand", |
| 78 | + [ExtensionKind.BitwiseLeftShiftOperatorMethodType]: "__luaBitwiseLeftShiftMethodBrand", |
| 79 | + [ExtensionKind.BitwiseRightShiftOperatorType]: "__luaBitwiseRightShiftBrand", |
| 80 | + [ExtensionKind.BitwiseRightShiftOperatorMethodType]: "__luaBitwiseRightShiftMethodBrand", |
| 81 | + [ExtensionKind.ConcatOperatorType]: "__luaConcatBrand", |
| 82 | + [ExtensionKind.ConcatOperatorMethodType]: "__luaConcatMethodBrand", |
| 83 | + [ExtensionKind.LessThanOperatorType]: "__luaLessThanBrand", |
| 84 | + [ExtensionKind.LessThanOperatorMethodType]: "__luaLessThanMethodBrand", |
| 85 | + [ExtensionKind.GreaterThanOperatorType]: "__luaGreaterThanBrand", |
| 86 | + [ExtensionKind.GreaterThanOperatorMethodType]: "__luaGreaterThanMethodBrand", |
| 87 | + [ExtensionKind.NegationOperatorType]: "__luaNegationBrand", |
| 88 | + [ExtensionKind.NegationOperatorMethodType]: "__luaNegationMethodBrand", |
| 89 | + [ExtensionKind.BitwiseNotOperatorType]: "__luaBitwiseNotBrand", |
| 90 | + [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", |
| 91 | + [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", |
| 92 | + [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", |
89 | 93 | }; |
90 | 94 |
|
91 | | -function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { |
92 | | - const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); |
93 | | - const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); |
94 | | - return extensionDirectory === sourceFileDirectory; |
| 95 | +export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { |
| 96 | + const typeBrand = extensionKindToTypeBrand[extensionKind]; |
| 97 | + return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; |
95 | 98 | } |
96 | 99 |
|
97 | | -export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { |
98 | | - const sourceFile = declaration.getSourceFile(); |
99 | | - if (isSourceFileFromLanguageExtensions(sourceFile)) { |
100 | | - if (ts.isFunctionDeclaration(declaration) && declaration.name?.text) { |
101 | | - const extensionKind = functionNameToExtensionKind[declaration.name.text]; |
102 | | - if (extensionKind) { |
103 | | - return extensionKind; |
104 | | - } |
105 | | - } |
106 | | - |
107 | | - if (ts.isTypeAliasDeclaration(declaration)) { |
108 | | - const extensionKind = typeNameToExtensionKind[declaration.name.text]; |
109 | | - if (extensionKind) { |
110 | | - return extensionKind; |
111 | | - } |
112 | | - } |
113 | | - |
114 | | - throw new Error("Unknown extension kind"); |
115 | | - } |
| 100 | +export function isExtensionFunction( |
| 101 | + context: TransformationContext, |
| 102 | + symbol: ts.Symbol, |
| 103 | + extensionKind: ExtensionKind |
| 104 | +): boolean { |
| 105 | + return ( |
| 106 | + symbol.getName() === extensionKindToFunctionName[extensionKind] && |
| 107 | + symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) |
| 108 | + ); |
116 | 109 | } |
0 commit comments