Skip to content

Commit ef25b25

Browse files
authored
Merge pull request microsoft#13940 from Microsoft/publicTransformers
Expose public API for transformation.
2 parents 03b9066 + 4db86f7 commit ef25b25

33 files changed

+1681
-1150
lines changed

Gulpfile.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const {runTestsInParallel} = mochaParallel;
4141
Error.stackTraceLimit = 1000;
4242

4343
const cmdLineOptions = minimist(process.argv.slice(2), {
44-
boolean: ["debug", "light", "colors", "lint", "soft"],
44+
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
4545
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
4646
alias: {
4747
d: "debug",
@@ -57,6 +57,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
5757
soft: false,
5858
colors: process.env.colors || process.env.color || true,
5959
debug: process.env.debug || process.env.d,
60+
inspect: process.env.inspect,
6061
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
6162
browser: process.env.browser || process.env.b || "IE",
6263
tests: process.env.test || process.env.tests || process.env.t,
@@ -597,6 +598,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
597598
cleanTestDirs((err) => {
598599
if (err) { console.error(err); failWithStatus(err, 1); }
599600
const debug = cmdLineOptions["debug"];
601+
const inspect = cmdLineOptions["inspect"];
600602
const tests = cmdLineOptions["tests"];
601603
const light = cmdLineOptions["light"];
602604
const stackTraceLimit = cmdLineOptions["stackTraceLimit"];
@@ -633,7 +635,10 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
633635
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
634636
if (!runInParallel) {
635637
const args = [];
636-
if (debug) {
638+
if (inspect) {
639+
args.push("--inspect");
640+
}
641+
if (inspect || debug) {
637642
args.push("--debug-brk");
638643
}
639644
args.push("-R", reporter);

Jakefile.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ var harnessSources = harnessCoreSources.concat([
131131
"matchFiles.ts",
132132
"initializeTSConfig.ts",
133133
"printer.ts",
134+
"transform.ts",
135+
"customTransforms.ts",
134136
].map(function (f) {
135137
return path.join(unittestsDirectory, f);
136138
})).concat([
@@ -792,6 +794,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
792794
}
793795

794796
var debug = process.env.debug || process.env.d;
797+
var inspect = process.env.inspect;
795798
tests = process.env.test || process.env.tests || process.env.t;
796799
var light = process.env.light || false;
797800
var stackTraceLimit = process.env.stackTraceLimit;
@@ -821,18 +824,39 @@ function runConsoleTests(defaultReporter, runInParallel) {
821824
testTimeout = 800000;
822825
}
823826

824-
colors = process.env.colors || process.env.color;
825-
colors = colors ? ' --no-colors ' : ' --colors ';
826-
reporter = process.env.reporter || process.env.r || defaultReporter;
827-
var bail = (process.env.bail || process.env.b) ? "--bail" : "";
827+
var colors = process.env.colors || process.env.color || true;
828+
var reporter = process.env.reporter || process.env.r || defaultReporter;
829+
var bail = process.env.bail || process.env.b;
828830
var lintFlag = process.env.lint !== 'false';
829831

830832
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
831833
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
832834
if (!runInParallel) {
833835
var startTime = mark();
834-
tests = tests ? ' -g "' + tests + '"' : '';
835-
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run;
836+
var args = [];
837+
if (inspect) {
838+
args.push("--inspect");
839+
}
840+
if (inspect || debug) {
841+
args.push("--debug-brk");
842+
}
843+
args.push("-R", reporter);
844+
if (tests) {
845+
args.push("-g", `"${tests}"`);
846+
}
847+
if (colors) {
848+
args.push("--colors");
849+
}
850+
else {
851+
args.push("--no-colors");
852+
}
853+
if (bail) {
854+
args.push("--bail");
855+
}
856+
args.push("-t", testTimeout);
857+
args.push(run);
858+
859+
var cmd = "mocha " + args.join(" ");
836860
console.log(cmd);
837861

838862
var savedNodeEnv = process.env.NODE_ENV;
@@ -853,7 +877,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
853877
var savedNodeEnv = process.env.NODE_ENV;
854878
process.env.NODE_ENV = "development";
855879
var startTime = mark();
856-
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) {
880+
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: !colors }, function (err) {
857881
process.env.NODE_ENV = savedNodeEnv;
858882
measure(startTime);
859883
// last worker clean everything and runs linter in case if there were no errors

src/compiler/checker.ts

Lines changed: 116 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ namespace ts {
6464
undefinedSymbol.declarations = [];
6565
const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments");
6666

67+
// for public members that accept a Node or one of its subtypes, we must guard against
68+
// synthetic nodes created during transformations by calling `getParseTreeNode`.
69+
// for most of these, we perform the guard only on `checker` to avoid any possible
70+
// extra cost of calling `getParseTreeNode` when calling these functions from inside the
71+
// checker.
6772
const checker: TypeChecker = {
6873
getNodeCount: () => sum(host.getSourceFiles(), "nodeCount"),
6974
getIdentifierCount: () => sum(host.getSourceFiles(), "identifierCount"),
@@ -74,8 +79,15 @@ namespace ts {
7479
isUnknownSymbol: symbol => symbol === unknownSymbol,
7580
getDiagnostics,
7681
getGlobalDiagnostics,
77-
getTypeOfSymbolAtLocation,
78-
getSymbolsOfParameterPropertyDeclaration,
82+
getTypeOfSymbolAtLocation: (symbol, location) => {
83+
location = getParseTreeNode(location);
84+
return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType;
85+
},
86+
getSymbolsOfParameterPropertyDeclaration: (parameter, parameterName) => {
87+
parameter = getParseTreeNode(parameter, isParameter);
88+
Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
89+
return getSymbolsOfParameterPropertyDeclaration(parameter, parameterName);
90+
},
7991
getDeclaredTypeOfSymbol,
8092
getPropertiesOfType,
8193
getPropertyOfType,
@@ -85,37 +97,88 @@ namespace ts {
8597
getBaseTypes,
8698
getBaseTypeOfLiteralType,
8799
getWidenedType,
88-
getTypeFromTypeNode,
100+
getTypeFromTypeNode: node => {
101+
node = getParseTreeNode(node, isTypeNode);
102+
return node ? getTypeFromTypeNode(node) : unknownType;
103+
},
89104
getParameterType: getTypeAtPosition,
90105
getReturnTypeOfSignature,
91106
getNonNullableType,
92-
getSymbolsInScope,
93-
getSymbolAtLocation,
94-
getShorthandAssignmentValueSymbol,
95-
getExportSpecifierLocalTargetSymbol,
96-
getTypeAtLocation: getTypeOfNode,
97-
getPropertySymbolOfDestructuringAssignment,
98-
signatureToString,
99-
typeToString,
107+
getSymbolsInScope: (location, meaning) => {
108+
location = getParseTreeNode(location);
109+
return location ? getSymbolsInScope(location, meaning) : [];
110+
},
111+
getSymbolAtLocation: node => {
112+
node = getParseTreeNode(node);
113+
return node ? getSymbolAtLocation(node) : undefined;
114+
},
115+
getShorthandAssignmentValueSymbol: node => {
116+
node = getParseTreeNode(node);
117+
return node ? getShorthandAssignmentValueSymbol(node) : undefined;
118+
},
119+
getExportSpecifierLocalTargetSymbol: node => {
120+
node = getParseTreeNode(node, isExportSpecifier);
121+
return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
122+
},
123+
getTypeAtLocation: node => {
124+
node = getParseTreeNode(node);
125+
return node ? getTypeOfNode(node) : unknownType;
126+
},
127+
getPropertySymbolOfDestructuringAssignment: location => {
128+
location = getParseTreeNode(location, isIdentifier);
129+
return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
130+
},
131+
signatureToString: (signature, enclosingDeclaration?, flags?, kind?) => {
132+
return signatureToString(signature, getParseTreeNode(enclosingDeclaration), flags, kind);
133+
},
134+
typeToString: (type, enclosingDeclaration?, flags?) => {
135+
return typeToString(type, getParseTreeNode(enclosingDeclaration), flags);
136+
},
100137
getSymbolDisplayBuilder,
101-
symbolToString,
138+
symbolToString: (symbol, enclosingDeclaration?, meaning?) => {
139+
return symbolToString(symbol, getParseTreeNode(enclosingDeclaration), meaning);
140+
},
102141
getAugmentedPropertiesOfType,
103142
getRootSymbols,
104-
getContextualType,
143+
getContextualType: node => {
144+
node = getParseTreeNode(node, isExpression)
145+
return node ? getContextualType(node) : undefined;
146+
},
105147
getFullyQualifiedName,
106-
getResolvedSignature,
107-
getConstantValue,
108-
isValidPropertyAccess,
109-
getSignatureFromDeclaration,
110-
isImplementationOfOverload,
148+
getResolvedSignature: (node, candidatesOutArray?) => {
149+
node = getParseTreeNode(node, isCallLikeExpression);
150+
return node ? getResolvedSignature(node, candidatesOutArray) : undefined;
151+
},
152+
getConstantValue: node => {
153+
node = getParseTreeNode(node, canHaveConstantValue);
154+
return node ? getConstantValue(node) : undefined;
155+
},
156+
isValidPropertyAccess: (node, propertyName) => {
157+
node = getParseTreeNode(node, isPropertyAccessOrQualifiedName);
158+
return node ? isValidPropertyAccess(node, propertyName) : false;
159+
},
160+
getSignatureFromDeclaration: declaration => {
161+
declaration = getParseTreeNode(declaration, isFunctionLike);
162+
return declaration ? getSignatureFromDeclaration(declaration) : undefined;
163+
},
164+
isImplementationOfOverload: node => {
165+
node = getParseTreeNode(node, isFunctionLike);
166+
return node ? isImplementationOfOverload(node) : undefined;
167+
},
111168
getAliasedSymbol: resolveAlias,
112169
getEmitResolver,
113170
getExportsOfModule: getExportsOfModuleAsArray,
114171
getExportsAndPropertiesOfModule,
115172
getAmbientModules,
116-
getAllAttributesTypeFromJsxOpeningLikeElement,
173+
getAllAttributesTypeFromJsxOpeningLikeElement: node => {
174+
node = getParseTreeNode(node, isJsxOpeningLikeElement);
175+
return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined;
176+
},
117177
getJsxIntrinsicTagNames,
118-
isOptionalParameter,
178+
isOptionalParameter: node => {
179+
node = getParseTreeNode(node, isParameter);
180+
return node ? isOptionalParameter(node) : false;
181+
},
119182
tryGetMemberInModuleExports,
120183
tryFindAmbientModuleWithoutAugmentations: moduleName => {
121184
// we deliberately exclude augmentations
@@ -20657,14 +20720,14 @@ namespace ts {
2065720720
}
2065820721

2065920722
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
20660-
const symbols = createMap<Symbol>();
20661-
let memberFlags: ModifierFlags = ModifierFlags.None;
20662-
2066320723
if (isInsideWithStatementBody(location)) {
2066420724
// We cannot answer semantic questions within a with block, do not proceed any further
2066520725
return [];
2066620726
}
2066720727

20728+
const symbols = createMap<Symbol>();
20729+
let memberFlags: ModifierFlags = ModifierFlags.None;
20730+
2066820731
populateSymbols();
2066920732

2067020733
return symbolsToArray(symbols);
@@ -20931,6 +20994,7 @@ namespace ts {
2093120994
if (node.kind === SyntaxKind.SourceFile) {
2093220995
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
2093320996
}
20997+
2093420998
if (isInsideWithStatementBody(node)) {
2093520999
// We cannot answer semantic questions within a with block, do not proceed any further
2093621000
return undefined;
@@ -21381,12 +21445,6 @@ namespace ts {
2138121445
}
2138221446

2138321447
function isValueAliasDeclaration(node: Node): boolean {
21384-
node = getParseTreeNode(node);
21385-
if (node === undefined) {
21386-
// A synthesized node comes from an emit transformation and is always a value.
21387-
return true;
21388-
}
21389-
2139021448
switch (node.kind) {
2139121449
case SyntaxKind.ImportEqualsDeclaration:
2139221450
case SyntaxKind.ImportClause:
@@ -21433,12 +21491,6 @@ namespace ts {
2143321491
}
2143421492

2143521493
function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean {
21436-
node = getParseTreeNode(node);
21437-
// Purely synthesized nodes are always emitted.
21438-
if (node === undefined) {
21439-
return true;
21440-
}
21441-
2144221494
if (isAliasSymbolDeclaration(node)) {
2144321495
const symbol = getSymbolOfNode(node);
2144421496
if (symbol && getSymbolLinks(symbol).referenced) {
@@ -21481,15 +21533,24 @@ namespace ts {
2148121533
}
2148221534

2148321535
function getNodeCheckFlags(node: Node): NodeCheckFlags {
21484-
node = getParseTreeNode(node);
21485-
return node ? getNodeLinks(node).flags : undefined;
21536+
return getNodeLinks(node).flags;
2148621537
}
2148721538

2148821539
function getEnumMemberValue(node: EnumMember): number {
2148921540
computeEnumMemberValues(<EnumDeclaration>node.parent);
2149021541
return getNodeLinks(node).enumMemberValue;
2149121542
}
2149221543

21544+
function canHaveConstantValue(node: Node): node is EnumMember | PropertyAccessExpression | ElementAccessExpression {
21545+
switch (node.kind) {
21546+
case SyntaxKind.EnumMember:
21547+
case SyntaxKind.PropertyAccessExpression:
21548+
case SyntaxKind.ElementAccessExpression:
21549+
return true;
21550+
}
21551+
return false;
21552+
}
21553+
2149321554
function getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number {
2149421555
if (node.kind === SyntaxKind.EnumMember) {
2149521556
return getEnumMemberValue(<EnumMember>node);
@@ -21671,10 +21732,21 @@ namespace ts {
2167121732
getReferencedImportDeclaration,
2167221733
getReferencedDeclarationWithCollidingName,
2167321734
isDeclarationWithCollidingName,
21674-
isValueAliasDeclaration,
21735+
isValueAliasDeclaration: node => {
21736+
node = getParseTreeNode(node);
21737+
// Synthesized nodes are always treated like values.
21738+
return node ? isValueAliasDeclaration(node) : true;
21739+
},
2167521740
hasGlobalName,
21676-
isReferencedAliasDeclaration,
21677-
getNodeCheckFlags,
21741+
isReferencedAliasDeclaration: (node, checkChildren?) => {
21742+
node = getParseTreeNode(node);
21743+
// Synthesized nodes are always treated as referenced.
21744+
return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
21745+
},
21746+
getNodeCheckFlags: node => {
21747+
node = getParseTreeNode(node);
21748+
return node ? getNodeCheckFlags(node) : undefined;
21749+
},
2167821750
isTopLevelValueImportEqualsWithEntityName,
2167921751
isDeclarationVisible,
2168021752
isImplementationOfOverload,
@@ -21685,7 +21757,10 @@ namespace ts {
2168521757
writeBaseConstructorTypeOfClass,
2168621758
isSymbolAccessible,
2168721759
isEntityNameVisible,
21688-
getConstantValue,
21760+
getConstantValue: node => {
21761+
node = getParseTreeNode(node, canHaveConstantValue);
21762+
return node ? getConstantValue(node) : undefined;
21763+
},
2168921764
collectLinkedAliases,
2169021765
getReferencedValueDeclaration,
2169121766
getTypeReferenceSerializationKind,

0 commit comments

Comments
 (0)