Skip to content

Commit 2137cb0

Browse files
committed
feat: json encoded annotations
feat: support companion extensions on interface and type fix: overly permissive isCompanionReference fix: call extensions feat: import json extension definitions from package.json
1 parent 6bc9bb8 commit 2137cb0

File tree

16 files changed

+420
-89
lines changed

16 files changed

+420
-89
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @tsplus type companions-everwhere/A
3+
* @tsplus companion companions-everywhere/AOps
4+
*/
5+
export type A = {}
6+
7+
/**
8+
* @tsplus static companions-everywhere/AOps get
9+
*/
10+
export const get: A = {}
11+
12+
/**
13+
* @tsplus static companions-everywhere/AOps __call
14+
*/
15+
export const callA = (): A => ({})
16+
17+
class X {}
18+
19+
new X()
20+
X
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"@fp-ts/core/Async": [
3+
{
4+
"definitionName": "Async",
5+
"definitionKind": "interface",
6+
"extensions": [
7+
{
8+
"kind": "type",
9+
"typeName": "fp-ts/Async"
10+
},
11+
{
12+
"kind": "companion",
13+
"typeName": "fp-ts/AsyncOps"
14+
}
15+
]
16+
},
17+
{
18+
"definitionName": "fromSync",
19+
"definitionKind": "const",
20+
"extensions": [
21+
{
22+
"kind": "static",
23+
"typeName": "fp-ts/AsyncOps",
24+
"name": "fromSync"
25+
}
26+
]
27+
},
28+
{
29+
"definitionName": "delay",
30+
"definitionKind": "const",
31+
"extensions": [
32+
{
33+
"kind": "pipeable",
34+
"typeName": "fp-ts/Async",
35+
"name": "delay"
36+
}
37+
]
38+
},
39+
{
40+
"definitionName": "map",
41+
"definitionKind": "const",
42+
"extensions": [
43+
{
44+
"kind": "pipeable",
45+
"typeName": "fp-ts/Async",
46+
"name": "map"
47+
}
48+
]
49+
}
50+
]
51+
}

effect/packages/package2/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"build:esm": "node ../../../built/local/tsc.js -p ./tsconfig.json"
66
},
77
"dependencies": {
8+
"@fp-ts/core": "0.0.2",
89
"@tsplus-test/package1": "*"
910
}
1011
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { Async } from '@fp-ts/core/Async'
2+
3+
Async.fromSync(() => console.log("Fluent in fp-ts!")).delay(1)
4+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Effect.succeed(() => 1)
22

3-
Maybe.just("A")
3+
Maybe.just("A")

effect/packages/package2/src/prelude.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ import { Effect, T, chain, chainPipeable } from "@tsplus-test/package1/prelude"
66
/**
77
* @tsplus global
88
*/
9-
import { Maybe, Just } from "@tsplus-test/package1/prelude/definition/Maybe"
9+
import { Maybe, Just } from "@tsplus-test/package1/prelude/definition/Maybe"
10+

effect/packages/package2/tsconfig.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
"declarationDir": "build/dts",
77
"tsPlusConfig": "../../tsplus.config.json",
88
"noUnusedLocals": true,
9-
"noUnusedParameters": true
9+
"noUnusedParameters": true,
10+
"tsPlusTypes": [
11+
"./fp-ts__core.json"
12+
]
1013
},
1114
"include": ["src/**/*.ts"]
1215
}

src/compiler/checker.ts

Lines changed: 96 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,7 @@ namespace ts {
826826
getIndexAccessExpressionCache: () => indexAccessExpressionCache,
827827
isTsPlusMacroCall,
828828
isTsPlusMacroGetter,
829-
isClassCompanionReference,
829+
isCompanionReference,
830830
collectTsPlusFluentTags,
831831
hasExportedPlusTags: (declaration) => {
832832
return collectTsPlusFluentTags(declaration).length > 0 ||
@@ -1196,7 +1196,7 @@ namespace ts {
11961196
const copy: ESMap<string, Symbol> = new Map();
11971197
const copyFluent: ESMap<string, Set<TsPlusFluentExtension>> = new Map();
11981198
symbols.forEach((target) => {
1199-
if (typeSymbolCache.has(target) && !isClassCompanionReference(selfNode)) {
1199+
if (typeSymbolCache.has(target) && !isCompanionReference(selfNode)) {
12001200
typeSymbolCache.get(target)!.forEach((typeSymbol) => {
12011201
const _static = staticCache.get(typeSymbol);
12021202
if (_static) {
@@ -1238,7 +1238,7 @@ namespace ts {
12381238
}
12391239
});
12401240
}
1241-
if (companionSymbolCache.has(target) && isClassCompanionReference(selfNode)) {
1241+
if (companionSymbolCache.has(target) && isCompanionReference(selfNode)) {
12421242
companionSymbolCache.get(target)!.forEach((typeSymbol) => {
12431243
const _static = staticCache.get(typeSymbol);
12441244
if (_static) {
@@ -2783,6 +2783,31 @@ namespace ts {
27832783
result = undefined;
27842784
}
27852785
}
2786+
// TSPLUS EXTENSION START
2787+
else {
2788+
if (originalLocation && originalLocation.parent && (isPropertyAccessExpression(originalLocation.parent) || isCallExpression(originalLocation.parent))) {
2789+
const symbol = location.locals.get(name)
2790+
if (symbol) {
2791+
if (companionSymbolCache.has(symbol)) {
2792+
result = symbol;
2793+
break loop;
2794+
}
2795+
if (symbol.exportSymbol && companionSymbolCache.has(symbol.exportSymbol)) {
2796+
result = symbol.exportSymbol;
2797+
break loop;
2798+
}
2799+
if (symbol.declarations && symbol.declarations[0] && isImportSpecifier(symbol.declarations[0])) {
2800+
const originalSymbol = getTargetOfImportSpecifier(symbol.declarations[0], false);
2801+
if (originalSymbol && companionSymbolCache.has(originalSymbol)) {
2802+
result = originalSymbol;
2803+
symbol.isReferenced = SymbolFlags.Value;
2804+
break loop;
2805+
}
2806+
}
2807+
}
2808+
}
2809+
}
2810+
// TSPLUS EXTENSION END
27862811
}
27872812
withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation);
27882813
switch (location.kind) {
@@ -3030,7 +3055,10 @@ namespace ts {
30303055
const globalImport = tsPlusGlobalImportCache.get(name as string);
30313056
if (globalImport) {
30323057
const targetSymbol = getTargetOfImportSpecifier(globalImport.importSpecifier, false);
3033-
if (targetSymbol && targetSymbol.flags & meaning) {
3058+
if (targetSymbol &&
3059+
((targetSymbol.flags & meaning) ||
3060+
companionSymbolCache.has(targetSymbol) && (isPropertyAccessExpression(originalLocation.parent) || isCallExpression(originalLocation.parent)))
3061+
) {
30343062
const withoutGlobals = resolveNameHelper(
30353063
originalLocation,
30363064
name,
@@ -5795,7 +5823,7 @@ namespace ts {
57955823
}
57965824

57975825
// TSPLUS EXTENSION START
5798-
function isClassCompanionReference(node: Expression | QualifiedName): boolean {
5826+
function isCompanionReference(node: Expression | QualifiedName): boolean {
57995827
let type: Type | undefined
58005828

58015829
const symbol = getSymbolAtLocation(node);
@@ -5809,8 +5837,8 @@ namespace ts {
58095837
if (!type) {
58105838
return false
58115839
}
5812-
5813-
return !!(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class);
5840+
return !!(getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class)
5841+
|| (!!symbol?.declarations?.[0] && (isInterfaceDeclaration(symbol.declarations[0]) || isTypeAliasDeclaration(symbol.declarations[0])))
58145842
}
58155843
// TSPLUS EXTENSION END
58165844

@@ -11023,6 +11051,13 @@ namespace ts {
1102311051
if (symbol.flags & SymbolFlags.Alias) {
1102411052
return getTypeOfAlias(symbol);
1102511053
}
11054+
if ((symbol.flags & SymbolFlags.Interface) || (symbol.flags & SymbolFlags.TypeAlias)) {
11055+
if (companionSymbolCache.has(symbol)) {
11056+
if (symbol.declarations?.[0]) {
11057+
return getTypeOfNode(symbol.declarations[0])
11058+
}
11059+
}
11060+
}
1102611061
return errorType;
1102711062
}
1102811063

@@ -30605,14 +30640,13 @@ namespace ts {
3060530640
if (nodeLinks.tsPlusResolvedType) {
3060630641
return nodeLinks.tsPlusResolvedType;
3060730642
}
30608-
if (isClassCompanionReference(_left)) {
30609-
const staticExt = getStaticCompanionExtension(leftType, right.escapedText.toString());
30610-
if (staticExt) {
30611-
nodeLinks.tsPlusStaticExtension = staticExt;
30612-
nodeLinks.tsPlusResolvedType = staticExt.type
30613-
return staticExt.type;
30643+
if (isCompanionReference(_left)) {
30644+
const companionExt = getStaticCompanionExtension(leftType, right.escapedText.toString());
30645+
if (companionExt) {
30646+
nodeLinks.tsPlusStaticExtension = companionExt;
30647+
nodeLinks.tsPlusResolvedType = companionExt.type
30648+
return companionExt.type;
3061430649
}
30615-
return;
3061630650
}
3061730651
const fluentExtType = getFluentExtension(leftType, right.escapedText.toString());
3061830652
if (fluentExtType && isCallExpression(node.parent) && node.parent.expression === node) {
@@ -32881,37 +32915,32 @@ namespace ts {
3288132915

3288232916
// TSPLUS EXTENSION START
3288332917
if (callSignatures.length === 0) {
32884-
if (isClassCompanionReference(node.expression)) {
32885-
const callExtension = getStaticCompanionExtension(apparentType, "__call");
32886-
32887-
if (callExtension) {
32888-
callSignatures = Array.from(getSignaturesOfType(getTypeOfSymbol(callExtension.patched), SignatureKind.Call));
32889-
callCache.set(node.expression, callExtension);
32890-
getNodeLinks(node).tsPlusCallExtension = callExtension;
32891-
}
32918+
let callExtension: TsPlusStaticFunctionExtension | undefined
32919+
if (isCompanionReference(node.expression)) {
32920+
callExtension = getStaticCompanionExtension(apparentType, "__call");
32921+
}
32922+
if (!callExtension) {
32923+
callExtension = getStaticExtension(apparentType, "__call");
32924+
}
32925+
if (callExtension) {
32926+
callSignatures = Array.from(getSignaturesOfType(getTypeOfSymbol(callExtension.patched), SignatureKind.Call));
32927+
callCache.set(node.expression, callExtension);
32928+
getNodeLinks(node).tsPlusCallExtension = callExtension;
3289232929
}
3289332930
else {
32894-
const callExtension = getStaticExtension(apparentType, "__call");
32895-
32896-
if (callExtension) {
32897-
callSignatures = Array.from(getSignaturesOfType(getTypeOfSymbol(callExtension.patched), SignatureKind.Call));
32898-
callCache.set(node.expression, callExtension);
32899-
getNodeLinks(node).tsPlusCallExtension = callExtension;
32900-
} else {
32901-
const callFluentExtensions = getFluentExtension(apparentType, "__call");
32902-
if (callFluentExtensions) {
32903-
callSignatures = Array.from(getSignaturesOfType(callFluentExtensions, SignatureKind.Call).map((s) => {
32904-
const sig = createTsPlusSignature(
32905-
(s as TsPlusSignature).tsPlusOriginal,
32906-
(s as TsPlusSignature).tsPlusExportName,
32907-
(s as TsPlusSignature).tsPlusFile
32908-
);
32909-
sig.tsPlusDeclaration = (s as TsPlusSignature).tsPlusDeclaration;
32910-
sig.tsPlusPipeable = (s as TsPlusSignature).tsPlusPipeable;
32911-
return sig;
32912-
}));
32913-
getNodeLinks(node).isFluentCall = true;
32914-
}
32931+
const callFluentExtensions = getFluentExtension(apparentType, "__call");
32932+
if (callFluentExtensions) {
32933+
callSignatures = Array.from(getSignaturesOfType(callFluentExtensions, SignatureKind.Call).map((s) => {
32934+
const sig = createTsPlusSignature(
32935+
(s as TsPlusSignature).tsPlusOriginal,
32936+
(s as TsPlusSignature).tsPlusExportName,
32937+
(s as TsPlusSignature).tsPlusFile
32938+
);
32939+
sig.tsPlusDeclaration = (s as TsPlusSignature).tsPlusDeclaration;
32940+
sig.tsPlusPipeable = (s as TsPlusSignature).tsPlusPipeable;
32941+
return sig;
32942+
}));
32943+
getNodeLinks(node).isFluentCall = true;
3291532944
}
3291632945
}
3291732946
}
@@ -45185,6 +45214,21 @@ namespace ts {
4518545214
symbols.set(id, symbol);
4518645215
}
4518745216
}
45217+
if (companionSymbolCache.has(symbol)) {
45218+
const id = symbol.escapedName;
45219+
if (!symbols.has(id)) {
45220+
symbols.set(id, symbol);
45221+
}
45222+
}
45223+
if (symbol.declarations && symbol.declarations[0] && isImportSpecifier(symbol.declarations[0])) {
45224+
const originalSymbol = getTargetOfImportSpecifier(symbol.declarations[0], false);
45225+
if (originalSymbol && companionSymbolCache.has(originalSymbol)) {
45226+
const id = symbol.escapedName;
45227+
if (!symbols.has(id)) {
45228+
symbols.set(id, symbol);
45229+
}
45230+
}
45231+
}
4518845232
}
4518945233

4519045234
function copySymbols(source: SymbolTable, meaning: SymbolFlags): void {
@@ -46764,7 +46808,7 @@ namespace ts {
4676446808
return [];
4676546809
}
4676646810
function collectTsPlusCompanionTags(declaration: Declaration) {
46767-
if (isClassDeclaration(declaration)) {
46811+
if (isClassDeclaration(declaration) || isInterfaceDeclaration(declaration) || isTypeAliasDeclaration(declaration)) {
4676846812
return declaration.tsPlusCompanionTags || [];
4676946813
}
4677046814
return [];
@@ -47368,15 +47412,21 @@ namespace ts {
4736847412
function getTsPlusSourceFileCache(tag: string) {
4736947413
return tsPlusFiles.has(tag) ? tsPlusFiles.get(tag)! : (tsPlusFiles.set(tag, new Set()), tsPlusFiles.get(tag)!);
4737047414
}
47371-
function cacheTsPlusCompanion(declaration: ClassDeclaration): void {
47372-
const type = getTypeOfNode(declaration);
47415+
function cacheTsPlusCompanion(declaration: ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration): void {
4737347416
const tags = collectTsPlusCompanionTags(declaration);
47417+
const type = getTypeOfNode(declaration)
4737447418
if (type.symbol) {
4737547419
for (const companionTag of tags) {
4737647420
getTsPlusSourceFileCache(companionTag).add(getSourceFileOfNode(declaration));
4737747421
addToCompanionSymbolCache(type.symbol, companionTag);
4737847422
}
4737947423
}
47424+
if (type.aliasSymbol) {
47425+
for (const companionTag of tags) {
47426+
getTsPlusSourceFileCache(companionTag).add(getSourceFileOfNode(declaration));
47427+
addToCompanionSymbolCache(type.aliasSymbol, companionTag);
47428+
}
47429+
}
4738047430
}
4738147431
function cacheTsPlusStaticVariable(file: SourceFile, declaration: VariableDeclarationWithIdentifier | ClassDeclarationWithIdentifier) {
4738247432
const staticTags = collectTsPlusStaticTags(declaration);

src/compiler/commandLineParser.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,15 @@ namespace ts {
208208
},
209209
{
210210
name: "tsPlusConfig",
211-
type: "string"
211+
type: "string",
212+
},
213+
{
214+
name: "tsPlusTypes",
215+
type: "list",
216+
element: {
217+
name: "tsPlusTypes",
218+
type: "string"
219+
},
212220
},
213221
{
214222
name: "transformers",

0 commit comments

Comments
 (0)