From 1238db98153e9610e2dc673e62b140607b1f0d62 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 17 Aug 2022 11:51:07 -0700 Subject: [PATCH 01/13] don't elide imports in JS files --- src/compiler/transformers/ts.ts | 8 ++-- tests/baselines/reference/elidedJSImport.js | 26 ++++++++++++ .../reference/elidedJSImport.symbols | 40 ++++++++++++++++++ .../baselines/reference/elidedJSImport.types | 41 +++++++++++++++++++ .../jsDeclarationsFunctionLikeClasses.js | 1 + ...wJsSynchronousCallErrors(module=node16).js | 9 ++++ ...sSynchronousCallErrors(module=nodenext).js | 9 ++++ tests/cases/compiler/elidedJSImport.ts | 24 +++++++++++ 8 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/elidedJSImport.js create mode 100644 tests/baselines/reference/elidedJSImport.symbols create mode 100644 tests/baselines/reference/elidedJSImport.types create mode 100644 tests/cases/compiler/elidedJSImport.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 61b982d7f2916..a5cfa6ad7674c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2455,9 +2455,11 @@ namespace ts { } function shouldEmitAliasDeclaration(node: Node): boolean { - return compilerOptions.preserveValueImports - ? resolver.isValueAliasDeclaration(node) - : resolver.isReferencedAliasDeclaration(node); + return isInJSFile(node) + ? true + : compilerOptions.preserveValueImports + ? resolver.isValueAliasDeclaration(node) + : resolver.isReferencedAliasDeclaration(node); } } } diff --git a/tests/baselines/reference/elidedJSImport.js b/tests/baselines/reference/elidedJSImport.js new file mode 100644 index 0000000000000..72eeecf091216 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/elidedJSImport.ts] //// + +//// [caller.js] +import * as fs from 'fs'; +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +console.log(fs); +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' + + +//// [index.d.ts] +declare module "@truffle/contract" { + // import { ContractObject } from "@truffle/contract-schema"; + interface ContractObject { + foo: number; + } + namespace TruffleContract { + export type Contract = ContractObject; + } + export default TruffleContract; +} + +//// [caller.js] +import * as fs from 'fs'; +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +console.log(fs); +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' diff --git a/tests/baselines/reference/elidedJSImport.symbols b/tests/baselines/reference/elidedJSImport.symbols new file mode 100644 index 0000000000000..0ad7292e528cb --- /dev/null +++ b/tests/baselines/reference/elidedJSImport.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/caller.js === +import * as fs from 'fs'; +>fs : Symbol(fs, Decl(caller.js, 0, 6)) + +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +>TruffleContract : Symbol(TruffleContract, Decl(caller.js, 1, 6)) + +console.log(fs); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>fs : Symbol(fs, Decl(caller.js, 0, 6)) + +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + + +=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === +declare module "@truffle/contract" { +>"@truffle/contract" : Symbol("@truffle/contract", Decl(index.d.ts, 0, 0)) + + // import { ContractObject } from "@truffle/contract-schema"; + interface ContractObject { +>ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) + + foo: number; +>foo : Symbol(ContractObject.foo, Decl(index.d.ts, 2, 30)) + } + namespace TruffleContract { +>TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 4, 5)) + + export type Contract = ContractObject; +>Contract : Symbol(Contract, Decl(index.d.ts, 5, 31)) +>ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) + } + export default TruffleContract; +>TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 4, 5)) +} diff --git a/tests/baselines/reference/elidedJSImport.types b/tests/baselines/reference/elidedJSImport.types new file mode 100644 index 0000000000000..e706354aa6c9b --- /dev/null +++ b/tests/baselines/reference/elidedJSImport.types @@ -0,0 +1,41 @@ +=== tests/cases/compiler/caller.js === +import * as fs from 'fs'; +>fs : error + +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +>TruffleContract : any + +console.log(fs); +>console.log(fs) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>fs : error + +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' +>console.log('TruffleContract is ', typeof TruffleContract, TruffleContract) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>'TruffleContract is ' : "TruffleContract is " +>typeof TruffleContract : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>TruffleContract : error +>TruffleContract : error + + +=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === +declare module "@truffle/contract" { +>"@truffle/contract" : typeof import("@truffle/contract") + + // import { ContractObject } from "@truffle/contract-schema"; + interface ContractObject { + foo: number; +>foo : number + } + namespace TruffleContract { + export type Contract = ContractObject; +>Contract : ContractObject + } + export default TruffleContract; +>TruffleContract : any +} diff --git a/tests/baselines/reference/jsDeclarationsFunctionLikeClasses.js b/tests/baselines/reference/jsDeclarationsFunctionLikeClasses.js index 9bc408c775824..20b5f16d1abbd 100644 --- a/tests/baselines/reference/jsDeclarationsFunctionLikeClasses.js +++ b/tests/baselines/reference/jsDeclarationsFunctionLikeClasses.js @@ -44,6 +44,7 @@ exports.Point = Point; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.magnitude = void 0; +var source_1 = require("./source"); /** * @param {Point} p */ diff --git a/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node16).js b/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node16).js index a02ef88f1e524..55189d86e6f14 100644 --- a/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node16).js +++ b/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=node16).js @@ -34,7 +34,13 @@ export async function h() { } //// [index.js] +import { createRequire as _createRequire } from "module"; +const __require = _createRequire(import.meta.url); +// esm format file +import { h as _h } from "./index.js"; +const mod = __require("./index.js"); import { f } from "./subfolder/index.js"; +const mod2 = __require("./subfolder/index.js"); export async function h() { const mod3 = await import("./index.js"); const mod4 = await import("./subfolder/index.js"); @@ -46,6 +52,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.f = void 0; // cjs format file const index_js_1 = require("../index.js"); +const mod = require("../index.js"); +const index_js_2 = require("./index.js"); +const mod2 = require("./index.js"); async function f() { const mod3 = await import("../index.js"); const mod4 = await import("./index.js"); diff --git a/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).js b/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).js index a02ef88f1e524..55189d86e6f14 100644 --- a/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).js +++ b/tests/baselines/reference/nodeModulesAllowJsSynchronousCallErrors(module=nodenext).js @@ -34,7 +34,13 @@ export async function h() { } //// [index.js] +import { createRequire as _createRequire } from "module"; +const __require = _createRequire(import.meta.url); +// esm format file +import { h as _h } from "./index.js"; +const mod = __require("./index.js"); import { f } from "./subfolder/index.js"; +const mod2 = __require("./subfolder/index.js"); export async function h() { const mod3 = await import("./index.js"); const mod4 = await import("./subfolder/index.js"); @@ -46,6 +52,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.f = void 0; // cjs format file const index_js_1 = require("../index.js"); +const mod = require("../index.js"); +const index_js_2 = require("./index.js"); +const mod2 = require("./index.js"); async function f() { const mod3 = await import("../index.js"); const mod4 = await import("./index.js"); diff --git a/tests/cases/compiler/elidedJSImport.ts b/tests/cases/compiler/elidedJSImport.ts new file mode 100644 index 0000000000000..7c70d8dafd84b --- /dev/null +++ b/tests/cases/compiler/elidedJSImport.ts @@ -0,0 +1,24 @@ +// @allowJs: true +// @checkJs: false +// @module: ES2020 +// @moduleResolution: node +// @outDir: out + +// @Filename: caller.js +import * as fs from 'fs'; +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +console.log(fs); +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' + + +// @Filename: node_modules/@truffle/contract/index.d.ts +declare module "@truffle/contract" { + // import { ContractObject } from "@truffle/contract-schema"; + interface ContractObject { + foo: number; + } + namespace TruffleContract { + export type Contract = ContractObject; + } + export default TruffleContract; +} \ No newline at end of file From 68021c1a0e986549bc47699f5e3139a4f58edb73 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 22 Aug 2022 10:11:58 -0700 Subject: [PATCH 02/13] WIP: get rid of caching of resolved symbol, add transform tests --- src/compiler/checker.ts | 44 +++++++++-- tests/baselines/reference/elidedJSImport2.js | 77 +++++++++++++++++++ .../reference/elidedJSImport2.symbols | 50 ++++++++++++ .../baselines/reference/elidedJSImport2.types | 55 +++++++++++++ tests/cases/compiler/elidedJSImport2.ts | 31 ++++++++ 5 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/elidedJSImport2.js create mode 100644 tests/baselines/reference/elidedJSImport2.symbols create mode 100644 tests/baselines/reference/elidedJSImport2.types create mode 100644 tests/cases/compiler/elidedJSImport2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dff83b717ec13..88da8ef89204e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43070,10 +43070,10 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedValueSymbol(node); + const symbol = getReferencedValueSymbol(node); // >> Change it here // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol - if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { + if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { // >> Probably use the default excludes now return getDeclarationOfAliasSymbol(symbol); } } @@ -43456,10 +43456,10 @@ namespace ts { } function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { - const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; - if (resolvedSymbol) { - return resolvedSymbol; - } + // const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + // if (resolvedSymbol) { + // return resolvedSymbol; + // } let location: Node = reference; if (startInDeclarationContainer) { @@ -43474,6 +43474,38 @@ namespace ts { return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } + // function getReferencedAnySymbolOld(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { + // // >> Can't use cached resolved symbol because it might be `unknown` symbol + // // const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + // // if (resolvedSymbol) { + // // return resolvedSymbol; + // // } + + // let location: Node = reference; + // if (startInDeclarationContainer) { + // // When resolving the name of a declaration as a value, we need to start resolution + // // at a point outside of the declaration. + // const parent = reference.parent; + // if (isDeclaration(parent) && reference === parent.name) { + // location = getDeclarationContainer(parent); + // } + // } + + // // return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); + // return resolveNameHelper( + // location, + // reference.escapedText, + // SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, + // /*nameNotFoundMessage*/ undefined, + // /*nameArg*/ undefined, + // /*isUse*/ true, + // /*excludeGlobals*/ false, + // /*getSpellingSuggestions*/ true, + // (symbol, name, _meaning) => getSymbol(symbol, name, SymbolFlags.All), + // // /*reportErrors*/ false, + // ); + // } + function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { if (!isGeneratedIdentifier(referenceIn)) { const reference = getParseTreeNode(referenceIn, isIdentifier); diff --git a/tests/baselines/reference/elidedJSImport2.js b/tests/baselines/reference/elidedJSImport2.js new file mode 100644 index 0000000000000..97f1e62b1a840 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2.js @@ -0,0 +1,77 @@ +//// [tests/cases/compiler/elidedJSImport2.ts] //// + +//// [index.js] +import { Foo } from "./other.js"; +import * as other from "./other.js"; +import defaultFoo from "./other.js"; + +const x = new Foo(); +const y = other.Foo(); +const z = new defaultFoo(); + +//// [other.d.ts] +export interface Foo { + bar: number; +} + +export default interface Bar { + foo: number; +} + +//// [other.js] +export class Foo { + bar = 2.4; +} + +export default class Bar { + foo = 1.2; +} + + +//// [index.js] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const other_js_1 = require("./other.js"); +const other = __importStar(require("./other.js")); +const other_js_2 = __importDefault(require("./other.js")); +const x = new other_js_1.Foo(); +const y = other.Foo(); +const z = new other_js_2.default(); +//// [other.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Foo = void 0; +class Foo { + bar = 2.4; +} +exports.Foo = Foo; +class Bar { + foo = 1.2; +} +exports.default = Bar; diff --git a/tests/baselines/reference/elidedJSImport2.symbols b/tests/baselines/reference/elidedJSImport2.symbols new file mode 100644 index 0000000000000..600c33b51ea6a --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : Symbol(Foo, Decl(index.js, 0, 8)) + +import * as other from "./other.js"; +>other : Symbol(other, Decl(index.js, 1, 6)) + +import defaultFoo from "./other.js"; +>defaultFoo : Symbol(defaultFoo, Decl(index.js, 2, 6)) + +const x = new Foo(); +>x : Symbol(x, Decl(index.js, 4, 5)) + +const y = other.Foo(); +>y : Symbol(y, Decl(index.js, 5, 5)) +>other : Symbol(other, Decl(index.js, 1, 6)) + +const z = new defaultFoo(); +>z : Symbol(z, Decl(index.js, 6, 5)) + +=== tests/cases/compiler/other.d.ts === +export interface Foo { +>Foo : Symbol(Foo, Decl(other.d.ts, 0, 0)) + + bar: number; +>bar : Symbol(Foo.bar, Decl(other.d.ts, 0, 22)) +} + +export default interface Bar { +>Bar : Symbol(Bar, Decl(other.d.ts, 2, 1)) + + foo: number; +>foo : Symbol(Bar.foo, Decl(other.d.ts, 4, 30)) +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Symbol(Foo, Decl(other.js, 0, 0)) + + bar = 2.4; +>bar : Symbol(Foo.bar, Decl(other.js, 0, 18)) +} + +export default class Bar { +>Bar : Symbol(Bar, Decl(other.js, 2, 1)) + + foo = 1.2; +>foo : Symbol(Bar.foo, Decl(other.js, 4, 26)) +} + diff --git a/tests/baselines/reference/elidedJSImport2.types b/tests/baselines/reference/elidedJSImport2.types new file mode 100644 index 0000000000000..3fd9545220317 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2.types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : any + +import * as other from "./other.js"; +>other : typeof other + +import defaultFoo from "./other.js"; +>defaultFoo : any + +const x = new Foo(); +>x : error +>new Foo() : error +>Foo : error + +const y = other.Foo(); +>y : error +>other.Foo() : error +>other.Foo : error +>other : typeof other +>Foo : any + +const z = new defaultFoo(); +>z : error +>new defaultFoo() : error +>defaultFoo : error + +=== tests/cases/compiler/other.d.ts === +export interface Foo { + bar: number; +>bar : number +} + +export default interface Bar { + foo: number; +>foo : number +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Foo + + bar = 2.4; +>bar : number +>2.4 : 2.4 +} + +export default class Bar { +>Bar : Bar + + foo = 1.2; +>foo : number +>1.2 : 1.2 +} + diff --git a/tests/cases/compiler/elidedJSImport2.ts b/tests/cases/compiler/elidedJSImport2.ts new file mode 100644 index 0000000000000..79ff804743a6e --- /dev/null +++ b/tests/cases/compiler/elidedJSImport2.ts @@ -0,0 +1,31 @@ +// @allowJs: true +// @checkJs: false +// @module: node16 +// @outDir: out + +// @Filename: index.js +import { Foo } from "./other.js"; +import * as other from "./other.js"; +import defaultFoo from "./other.js"; + +const x = new Foo(); +const y = other.Foo(); +const z = new defaultFoo(); + +// @Filename: other.d.ts +export interface Foo { + bar: number; +} + +export default interface Bar { + foo: number; +} + +// @Filename: other.js +export class Foo { + bar = 2.4; +} + +export default class Bar { + foo = 1.2; +} From 2aa5bfe01d26633c9ee7832005cc220787e3b7b6 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 22 Aug 2022 10:24:31 -0700 Subject: [PATCH 03/13] get rid of caching only for resolver functions --- src/compiler/checker.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 88da8ef89204e..cdf0e42e04ff0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43035,7 +43035,7 @@ namespace ts { // declaration, we need to start resolution at the declaration's container. // Otherwise, we could incorrectly resolve the export container as the // declaration if it contains an exported member with the same name. - let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); + let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node), /*useCache*/ false); // >> change here if (symbol) { if (symbol.flags & SymbolFlags.ExportValue) { // If we reference an exported entity within the same module declaration, then whether @@ -43070,7 +43070,7 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedValueSymbol(node); // >> Change it here + const symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ undefined, /*useCache*/ false); // >> Change it here // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { // >> Probably use the default excludes now @@ -43455,11 +43455,13 @@ namespace ts { return globals.has(escapeLeadingUnderscores(name)); } - function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { - // const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; - // if (resolvedSymbol) { - // return resolvedSymbol; - // } + function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean, useCache = true): Symbol | undefined { // TODO: if we change this to return any kind of symbol, then rename it + if (useCache) { + const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + if (resolvedSymbol) { + return resolvedSymbol; + } + } let location: Node = reference; if (startInDeclarationContainer) { From 0c6f9c744d2eeea7a2ffcfba58ec0b63a70727d5 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Wed, 24 Aug 2022 16:13:38 -0700 Subject: [PATCH 04/13] use getReferencedSymbol instead of getReferencedValueSymbol in module transform --- src/compiler/checker.ts | 61 ++++++++----------- .../allowImportClausesToMergeWithTypes.js | 2 +- .../jsxCheckJsxNoTypeArgumentsAllowed.js | 2 +- .../reference/noCrashOnImportShadowing.js | 2 +- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cdf0e42e04ff0..b03362f31ead0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43035,7 +43035,7 @@ namespace ts { // declaration, we need to start resolution at the declaration's container. // Otherwise, we could incorrectly resolve the export container as the // declaration if it contains an exported member with the same name. - let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node), /*useCache*/ false); // >> change here + let symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); // >> change here if (symbol) { if (symbol.flags & SymbolFlags.ExportValue) { // If we reference an exported entity within the same module declaration, then whether @@ -43070,9 +43070,9 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ undefined, /*useCache*/ false); // >> Change it here + const symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ undefined); // >> Change it here // We should only get the declaration of an alias if there isn't a local value - // declaration for the symbol + // declaration for the symbol // >> UPDATE THIS if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { // >> Probably use the default excludes now return getDeclarationOfAliasSymbol(symbol); } @@ -43455,7 +43455,7 @@ namespace ts { return globals.has(escapeLeadingUnderscores(name)); } - function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean, useCache = true): Symbol | undefined { // TODO: if we change this to return any kind of symbol, then rename it + function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean, useCache = true): Symbol | undefined { // >> TODO: if we change this to return any kind of symbol, then rename it if (useCache) { const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; if (resolvedSymbol) { @@ -43476,37 +43476,30 @@ namespace ts { return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } - // function getReferencedAnySymbolOld(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { - // // >> Can't use cached resolved symbol because it might be `unknown` symbol - // // const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; - // // if (resolvedSymbol) { - // // return resolvedSymbol; - // // } - - // let location: Node = reference; - // if (startInDeclarationContainer) { - // // When resolving the name of a declaration as a value, we need to start resolution - // // at a point outside of the declaration. - // const parent = reference.parent; - // if (isDeclaration(parent) && reference === parent.name) { - // location = getDeclarationContainer(parent); - // } - // } + function getReferencedSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { // >> TODO + const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + if (resolvedSymbol && resolvedSymbol !== unknownSymbol) { + return resolvedSymbol; + } - // // return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); - // return resolveNameHelper( - // location, - // reference.escapedText, - // SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, - // /*nameNotFoundMessage*/ undefined, - // /*nameArg*/ undefined, - // /*isUse*/ true, - // /*excludeGlobals*/ false, - // /*getSpellingSuggestions*/ true, - // (symbol, name, _meaning) => getSymbol(symbol, name, SymbolFlags.All), - // // /*reportErrors*/ false, - // ); - // } + let location: Node = reference; + if (startInDeclarationContainer) { + // When resolving the name of a declaration as a value, we need to start resolution + // at a point outside of the declaration. + const parent = reference.parent; + if (isDeclaration(parent) && reference === parent.name) { + location = getDeclarationContainer(parent); + } + } + + return resolveName( + location, + reference.escapedText, + SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, // >> update symbol flags? + /*nodeNotFoundMessage*/ undefined, + /*nameArg*/ undefined, + /*isUse*/ true); + } function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { if (!isGeneratedIdentifier(referenceIn)) { diff --git a/tests/baselines/reference/allowImportClausesToMergeWithTypes.js b/tests/baselines/reference/allowImportClausesToMergeWithTypes.js index 9c50acdfb1a90..8c171dbfceae3 100644 --- a/tests/baselines/reference/allowImportClausesToMergeWithTypes.js +++ b/tests/baselines/reference/allowImportClausesToMergeWithTypes.js @@ -45,7 +45,7 @@ b_1["default"]; "use strict"; exports.__esModule = true; var x = { x: "" }; -zzz; +a_1["default"]; var b_1 = require("./b"); b_1["default"]; var y = x; diff --git a/tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.js b/tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.js index a1a7692ca7655..2a2bca568b864 100644 --- a/tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.js +++ b/tests/baselines/reference/jsxCheckJsxNoTypeArgumentsAllowed.js @@ -23,5 +23,5 @@ let x = a={10} b="hi" />; // error, no type arguments in js exports.__esModule = true; var component_1 = require("./component"); var React = require("react"); -var x = , a={10} b="hi" />; // error, no type arguments in js +var x = , a={10} b="hi" />; // error, no type arguments in js ; diff --git a/tests/baselines/reference/noCrashOnImportShadowing.js b/tests/baselines/reference/noCrashOnImportShadowing.js index d02e861f20349..9c8ff2f8452f3 100644 --- a/tests/baselines/reference/noCrashOnImportShadowing.js +++ b/tests/baselines/reference/noCrashOnImportShadowing.js @@ -41,7 +41,7 @@ B.zzz; "use strict"; exports.__esModule = true; var x = { x: "" }; -B.zzz; +a_1.B.zzz; var OriginalB = require("./b"); OriginalB.zzz; var y = x; From ef5b062072c017e4fb0ce7656d0adadda218f037 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Thu, 25 Aug 2022 13:55:22 -0700 Subject: [PATCH 05/13] WIP: add reportErrors flag to resolveName --- src/compiler/checker.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b03362f31ead0..174ceacb12cac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1850,7 +1850,8 @@ namespace ts { isUse: boolean, excludeGlobals: boolean, getSpellingSuggestions: boolean, - lookup: typeof getSymbol): Symbol | undefined { + lookup: typeof getSymbol, + reportErrors = true): Symbol | undefined { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location let result: Symbol | undefined; let lastLocation: Node | undefined; @@ -2011,7 +2012,9 @@ namespace ts { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. - error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); + if (reportErrors) { + error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); + } return undefined; } break loop; @@ -2029,7 +2032,7 @@ namespace ts { if (lastLocation === (location as ExpressionWithTypeArguments).expression && (location.parent as HeritageClause).token === SyntaxKind.ExtendsKeyword) { const container = location.parent.parent; if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members!, name, meaning & SymbolFlags.Type))) { - if (nameNotFoundMessage) { + if (reportErrors && nameNotFoundMessage) { error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters); } return undefined; @@ -2049,7 +2052,9 @@ namespace ts { if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) { // A reference to this grandparent's type parameters would be an error if (result = lookup(getSymbolOfNode(grandparent as ClassLikeDeclaration | InterfaceDeclaration).members!, name, meaning & SymbolFlags.Type)) { - error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); + if (reportErrors) { + error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); + } return undefined; } } @@ -2206,7 +2211,7 @@ namespace ts { } if (!result) { - if (nameNotFoundMessage) { + if (reportErrors && nameNotFoundMessage) { addLazyDiagnostic(() => { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217 @@ -2259,7 +2264,7 @@ namespace ts { } return undefined; } - else if (checkAndReportErrorForInvalidInitializer()) { + else if (reportErrors && checkAndReportErrorForInvalidInitializer()) { return undefined; } From 589eb24bee90f56b05fbaa3d189b87cbaf72e260 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 26 Aug 2022 15:50:39 -0700 Subject: [PATCH 06/13] Import transformations now work correctly --- src/compiler/checker.ts | 12 ++++++++---- tests/cases/compiler/elidedJSImport.ts | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 174ceacb12cac..7ce20a68cccc9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43075,10 +43075,10 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ undefined); // >> Change it here + const symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ undefined); // We should only get the declaration of an alias if there isn't a local value - // declaration for the symbol // >> UPDATE THIS - if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { // >> Probably use the default excludes now + // declaration for the symbol + if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { return getDeclarationOfAliasSymbol(symbol); } } @@ -43497,10 +43497,14 @@ namespace ts { } } + // >> TODO: this comment is only valid for the use of 'getReferencedSymbol' in 'getReferencedImportDeclaration'. + // We get the symbol that has a value meaning, or is an alias. + // We'll only ever want a symbol that doesn't have a value meaning if it is also an import, + // and therefore if it has an alias meaning (because those type-resolving imports are not always elided e.g. in JS). return resolveName( location, reference.escapedText, - SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, // >> update symbol flags? + SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); diff --git a/tests/cases/compiler/elidedJSImport.ts b/tests/cases/compiler/elidedJSImport.ts index 7c70d8dafd84b..1cf9756660fc5 100644 --- a/tests/cases/compiler/elidedJSImport.ts +++ b/tests/cases/compiler/elidedJSImport.ts @@ -1,6 +1,6 @@ // @allowJs: true // @checkJs: false -// @module: ES2020 +// @module: ES2020, commonjs // @moduleResolution: node // @outDir: out From b5c0ec6fabcd79d9198807944a8c4e291498b039 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Fri, 26 Aug 2022 15:54:36 -0700 Subject: [PATCH 07/13] don't emit diagnostics when looking up referenced symbol --- src/compiler/checker.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ce20a68cccc9..58d37fbabb4f2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1837,8 +1837,9 @@ namespace ts { nameArg: __String | Identifier | undefined, isUse: boolean, excludeGlobals = false, - getSpellingSuggstions = true): Symbol | undefined { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggstions, getSymbol); + getSpellingSuggestions = true, + reportErrors = true): Symbol | undefined { + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggestions, getSymbol, reportErrors); } function resolveNameHelper( @@ -2269,7 +2270,7 @@ namespace ts { } // Perform extra checks only if error reporting was requested - if (nameNotFoundMessage) { + if (reportErrors && nameNotFoundMessage) { addLazyDiagnostic(() => { // Only check for block-scoped variable if we have an error location and are looking for the // name with variable meaning @@ -43507,7 +43508,10 @@ namespace ts { SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, - /*isUse*/ true); + /*isUse*/ true, + /*excludeGlobals*/ undefined, + /*getSpellingSuggestions*/ undefined, + /*reportErrors*/ false); } function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { From 07ff4b7b7939546101b7bf63fdda24a8cf3d6995 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 6 Sep 2022 11:49:45 -0700 Subject: [PATCH 08/13] small fixes and get rid of unnecessary comments --- src/compiler/checker.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58d37fbabb4f2..2160ea36b2a66 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43041,7 +43041,7 @@ namespace ts { // declaration, we need to start resolution at the declaration's container. // Otherwise, we could incorrectly resolve the export container as the // declaration if it contains an exported member with the same name. - let symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); // >> change here + let symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); if (symbol) { if (symbol.flags & SymbolFlags.ExportValue) { // If we reference an exported entity within the same module declaration, then whether @@ -43077,6 +43077,7 @@ namespace ts { const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { const symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ undefined); + // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { @@ -43461,12 +43462,10 @@ namespace ts { return globals.has(escapeLeadingUnderscores(name)); } - function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean, useCache = true): Symbol | undefined { // >> TODO: if we change this to return any kind of symbol, then rename it - if (useCache) { - const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; - if (resolvedSymbol) { - return resolvedSymbol; - } + function getReferencedValueSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { + const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + if (resolvedSymbol) { + return resolvedSymbol; } let location: Node = reference; @@ -43482,7 +43481,14 @@ namespace ts { return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } - function getReferencedSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { // >> TODO + /** + * Get either a value-meaning symbol or an alias symbol. + * Unlike `getReferencedValueSymbol`, if the cached resolved symbol is the unknown symbol, + * we call `resolveName` to find a symbol. + * This is because when caching the resolved symbol, we only consider value symbols, but here + * we want to also get an alias symbol if one exists. + */ + function getReferencedSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; if (resolvedSymbol && resolvedSymbol !== unknownSymbol) { return resolvedSymbol; @@ -43498,10 +43504,6 @@ namespace ts { } } - // >> TODO: this comment is only valid for the use of 'getReferencedSymbol' in 'getReferencedImportDeclaration'. - // We get the symbol that has a value meaning, or is an alias. - // We'll only ever want a symbol that doesn't have a value meaning if it is also an import, - // and therefore if it has an alias meaning (because those type-resolving imports are not always elided e.g. in JS). return resolveName( location, reference.escapedText, From feb0ab7b27751abf3f547d9af3b32dfeca68a8c6 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 6 Sep 2022 13:50:36 -0700 Subject: [PATCH 09/13] update tests --- .../reference/elidedJSImport1.errors.txt | 31 +++++++ tests/baselines/reference/elidedJSImport1.js | 25 ++++++ .../reference/elidedJSImport1.symbols | 39 +++++++++ .../baselines/reference/elidedJSImport1.types | 40 +++++++++ .../elidedJSImport2(module=commonjs).js | 83 +++++++++++++++++++ .../elidedJSImport2(module=commonjs).symbols | 50 +++++++++++ .../elidedJSImport2(module=commonjs).types | 55 ++++++++++++ .../elidedJSImport2(module=es2022).js | 52 ++++++++++++ .../elidedJSImport2(module=es2022).symbols | 50 +++++++++++ .../elidedJSImport2(module=es2022).types | 55 ++++++++++++ .../{elidedJSImport.ts => elidedJSImport1.ts} | 5 +- tests/cases/compiler/elidedJSImport2.ts | 6 +- 12 files changed, 487 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/elidedJSImport1.errors.txt create mode 100644 tests/baselines/reference/elidedJSImport1.js create mode 100644 tests/baselines/reference/elidedJSImport1.symbols create mode 100644 tests/baselines/reference/elidedJSImport1.types create mode 100644 tests/baselines/reference/elidedJSImport2(module=commonjs).js create mode 100644 tests/baselines/reference/elidedJSImport2(module=commonjs).symbols create mode 100644 tests/baselines/reference/elidedJSImport2(module=commonjs).types create mode 100644 tests/baselines/reference/elidedJSImport2(module=es2022).js create mode 100644 tests/baselines/reference/elidedJSImport2(module=es2022).symbols create mode 100644 tests/baselines/reference/elidedJSImport2(module=es2022).types rename tests/cases/compiler/{elidedJSImport.ts => elidedJSImport1.ts} (81%) diff --git a/tests/baselines/reference/elidedJSImport1.errors.txt b/tests/baselines/reference/elidedJSImport1.errors.txt new file mode 100644 index 0000000000000..aff845926f910 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport1.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/caller.js(1,21): error TS2307: Cannot find module 'fs' or its corresponding type declarations. +tests/cases/compiler/caller.js(2,8): error TS18042: 'TruffleContract' is a type and cannot be imported in JavaScript files. Use 'import("@truffle/contract").TruffleContract' in a JSDoc type annotation. +tests/cases/compiler/caller.js(4,43): error TS2708: Cannot use namespace 'TruffleContract' as a value. +tests/cases/compiler/caller.js(4,60): error TS2708: Cannot use namespace 'TruffleContract' as a value. + + +==== tests/cases/compiler/caller.js (4 errors) ==== + import * as fs from 'fs'; + ~~~~ +!!! error TS2307: Cannot find module 'fs' or its corresponding type declarations. + import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform + ~~~~~~~~~~~~~~~ +!!! error TS18042: 'TruffleContract' is a type and cannot be imported in JavaScript files. Use 'import("@truffle/contract").TruffleContract' in a JSDoc type annotation. + console.log(fs); + console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' + ~~~~~~~~~~~~~~~ +!!! error TS2708: Cannot use namespace 'TruffleContract' as a value. + ~~~~~~~~~~~~~~~ +!!! error TS2708: Cannot use namespace 'TruffleContract' as a value. + + +==== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts (0 errors) ==== + declare module "@truffle/contract" { + interface ContractObject { + foo: number; + } + namespace TruffleContract { + export type Contract = ContractObject; + } + export default TruffleContract; + } \ No newline at end of file diff --git a/tests/baselines/reference/elidedJSImport1.js b/tests/baselines/reference/elidedJSImport1.js new file mode 100644 index 0000000000000..33b1a1f9a32b1 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport1.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/elidedJSImport1.ts] //// + +//// [caller.js] +import * as fs from 'fs'; +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +console.log(fs); +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' + + +//// [index.d.ts] +declare module "@truffle/contract" { + interface ContractObject { + foo: number; + } + namespace TruffleContract { + export type Contract = ContractObject; + } + export default TruffleContract; +} + +//// [caller.js] +import * as fs from 'fs'; +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +console.log(fs); +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' diff --git a/tests/baselines/reference/elidedJSImport1.symbols b/tests/baselines/reference/elidedJSImport1.symbols new file mode 100644 index 0000000000000..9620fb823671a --- /dev/null +++ b/tests/baselines/reference/elidedJSImport1.symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/caller.js === +import * as fs from 'fs'; +>fs : Symbol(fs, Decl(caller.js, 0, 6)) + +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +>TruffleContract : Symbol(TruffleContract, Decl(caller.js, 1, 6)) + +console.log(fs); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>fs : Symbol(fs, Decl(caller.js, 0, 6)) + +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + + +=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === +declare module "@truffle/contract" { +>"@truffle/contract" : Symbol("@truffle/contract", Decl(index.d.ts, 0, 0)) + + interface ContractObject { +>ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) + + foo: number; +>foo : Symbol(ContractObject.foo, Decl(index.d.ts, 1, 30)) + } + namespace TruffleContract { +>TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 3, 5)) + + export type Contract = ContractObject; +>Contract : Symbol(Contract, Decl(index.d.ts, 4, 31)) +>ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) + } + export default TruffleContract; +>TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 3, 5)) +} diff --git a/tests/baselines/reference/elidedJSImport1.types b/tests/baselines/reference/elidedJSImport1.types new file mode 100644 index 0000000000000..331f18e3cc4af --- /dev/null +++ b/tests/baselines/reference/elidedJSImport1.types @@ -0,0 +1,40 @@ +=== tests/cases/compiler/caller.js === +import * as fs from 'fs'; +>fs : any + +import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform +>TruffleContract : any + +console.log(fs); +>console.log(fs) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>fs : any + +console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' +>console.log('TruffleContract is ', typeof TruffleContract, TruffleContract) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>'TruffleContract is ' : "TruffleContract is " +>typeof TruffleContract : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>TruffleContract : any +>TruffleContract : any + + +=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === +declare module "@truffle/contract" { +>"@truffle/contract" : typeof import("@truffle/contract") + + interface ContractObject { + foo: number; +>foo : number + } + namespace TruffleContract { + export type Contract = ContractObject; +>Contract : ContractObject + } + export default TruffleContract; +>TruffleContract : any +} diff --git a/tests/baselines/reference/elidedJSImport2(module=commonjs).js b/tests/baselines/reference/elidedJSImport2(module=commonjs).js new file mode 100644 index 0000000000000..a98e850e2a52d --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=commonjs).js @@ -0,0 +1,83 @@ +//// [tests/cases/compiler/elidedJSImport2.ts] //// + +//// [index.js] +import { Foo } from "./other.js"; +import * as other from "./other.js"; +import defaultFoo from "./other.js"; + +const x = new Foo(); +const y = other.Foo(); +const z = new defaultFoo(); + +//// [other.d.ts] +export interface Foo { + bar: number; +} + +export default interface Bar { + foo: number; +} + +//// [other.js] +export class Foo { + bar = 2.4; +} + +export default class Bar { + foo = 1.2; +} + + +//// [index.js] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +exports.__esModule = true; +var other_js_1 = require("./other.js"); +var other = __importStar(require("./other.js")); +var other_js_2 = __importDefault(require("./other.js")); +var x = new other_js_1.Foo(); +var y = other.Foo(); +var z = new other_js_2["default"](); +//// [other.js] +"use strict"; +exports.__esModule = true; +exports.Foo = void 0; +var Foo = /** @class */ (function () { + function Foo() { + this.bar = 2.4; + } + return Foo; +}()); +exports.Foo = Foo; +var Bar = /** @class */ (function () { + function Bar() { + this.foo = 1.2; + } + return Bar; +}()); +exports["default"] = Bar; diff --git a/tests/baselines/reference/elidedJSImport2(module=commonjs).symbols b/tests/baselines/reference/elidedJSImport2(module=commonjs).symbols new file mode 100644 index 0000000000000..600c33b51ea6a --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=commonjs).symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : Symbol(Foo, Decl(index.js, 0, 8)) + +import * as other from "./other.js"; +>other : Symbol(other, Decl(index.js, 1, 6)) + +import defaultFoo from "./other.js"; +>defaultFoo : Symbol(defaultFoo, Decl(index.js, 2, 6)) + +const x = new Foo(); +>x : Symbol(x, Decl(index.js, 4, 5)) + +const y = other.Foo(); +>y : Symbol(y, Decl(index.js, 5, 5)) +>other : Symbol(other, Decl(index.js, 1, 6)) + +const z = new defaultFoo(); +>z : Symbol(z, Decl(index.js, 6, 5)) + +=== tests/cases/compiler/other.d.ts === +export interface Foo { +>Foo : Symbol(Foo, Decl(other.d.ts, 0, 0)) + + bar: number; +>bar : Symbol(Foo.bar, Decl(other.d.ts, 0, 22)) +} + +export default interface Bar { +>Bar : Symbol(Bar, Decl(other.d.ts, 2, 1)) + + foo: number; +>foo : Symbol(Bar.foo, Decl(other.d.ts, 4, 30)) +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Symbol(Foo, Decl(other.js, 0, 0)) + + bar = 2.4; +>bar : Symbol(Foo.bar, Decl(other.js, 0, 18)) +} + +export default class Bar { +>Bar : Symbol(Bar, Decl(other.js, 2, 1)) + + foo = 1.2; +>foo : Symbol(Bar.foo, Decl(other.js, 4, 26)) +} + diff --git a/tests/baselines/reference/elidedJSImport2(module=commonjs).types b/tests/baselines/reference/elidedJSImport2(module=commonjs).types new file mode 100644 index 0000000000000..3fd9545220317 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=commonjs).types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : any + +import * as other from "./other.js"; +>other : typeof other + +import defaultFoo from "./other.js"; +>defaultFoo : any + +const x = new Foo(); +>x : error +>new Foo() : error +>Foo : error + +const y = other.Foo(); +>y : error +>other.Foo() : error +>other.Foo : error +>other : typeof other +>Foo : any + +const z = new defaultFoo(); +>z : error +>new defaultFoo() : error +>defaultFoo : error + +=== tests/cases/compiler/other.d.ts === +export interface Foo { + bar: number; +>bar : number +} + +export default interface Bar { + foo: number; +>foo : number +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Foo + + bar = 2.4; +>bar : number +>2.4 : 2.4 +} + +export default class Bar { +>Bar : Bar + + foo = 1.2; +>foo : number +>1.2 : 1.2 +} + diff --git a/tests/baselines/reference/elidedJSImport2(module=es2022).js b/tests/baselines/reference/elidedJSImport2(module=es2022).js new file mode 100644 index 0000000000000..92669d94af86b --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=es2022).js @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/elidedJSImport2.ts] //// + +//// [index.js] +import { Foo } from "./other.js"; +import * as other from "./other.js"; +import defaultFoo from "./other.js"; + +const x = new Foo(); +const y = other.Foo(); +const z = new defaultFoo(); + +//// [other.d.ts] +export interface Foo { + bar: number; +} + +export default interface Bar { + foo: number; +} + +//// [other.js] +export class Foo { + bar = 2.4; +} + +export default class Bar { + foo = 1.2; +} + + +//// [index.js] +import { Foo } from "./other.js"; +import * as other from "./other.js"; +import defaultFoo from "./other.js"; +var x = new Foo(); +var y = other.Foo(); +var z = new defaultFoo(); +//// [other.js] +var Foo = /** @class */ (function () { + function Foo() { + this.bar = 2.4; + } + return Foo; +}()); +export { Foo }; +var Bar = /** @class */ (function () { + function Bar() { + this.foo = 1.2; + } + return Bar; +}()); +export default Bar; diff --git a/tests/baselines/reference/elidedJSImport2(module=es2022).symbols b/tests/baselines/reference/elidedJSImport2(module=es2022).symbols new file mode 100644 index 0000000000000..600c33b51ea6a --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=es2022).symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : Symbol(Foo, Decl(index.js, 0, 8)) + +import * as other from "./other.js"; +>other : Symbol(other, Decl(index.js, 1, 6)) + +import defaultFoo from "./other.js"; +>defaultFoo : Symbol(defaultFoo, Decl(index.js, 2, 6)) + +const x = new Foo(); +>x : Symbol(x, Decl(index.js, 4, 5)) + +const y = other.Foo(); +>y : Symbol(y, Decl(index.js, 5, 5)) +>other : Symbol(other, Decl(index.js, 1, 6)) + +const z = new defaultFoo(); +>z : Symbol(z, Decl(index.js, 6, 5)) + +=== tests/cases/compiler/other.d.ts === +export interface Foo { +>Foo : Symbol(Foo, Decl(other.d.ts, 0, 0)) + + bar: number; +>bar : Symbol(Foo.bar, Decl(other.d.ts, 0, 22)) +} + +export default interface Bar { +>Bar : Symbol(Bar, Decl(other.d.ts, 2, 1)) + + foo: number; +>foo : Symbol(Bar.foo, Decl(other.d.ts, 4, 30)) +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Symbol(Foo, Decl(other.js, 0, 0)) + + bar = 2.4; +>bar : Symbol(Foo.bar, Decl(other.js, 0, 18)) +} + +export default class Bar { +>Bar : Symbol(Bar, Decl(other.js, 2, 1)) + + foo = 1.2; +>foo : Symbol(Bar.foo, Decl(other.js, 4, 26)) +} + diff --git a/tests/baselines/reference/elidedJSImport2(module=es2022).types b/tests/baselines/reference/elidedJSImport2(module=es2022).types new file mode 100644 index 0000000000000..3fd9545220317 --- /dev/null +++ b/tests/baselines/reference/elidedJSImport2(module=es2022).types @@ -0,0 +1,55 @@ +=== tests/cases/compiler/index.js === +import { Foo } from "./other.js"; +>Foo : any + +import * as other from "./other.js"; +>other : typeof other + +import defaultFoo from "./other.js"; +>defaultFoo : any + +const x = new Foo(); +>x : error +>new Foo() : error +>Foo : error + +const y = other.Foo(); +>y : error +>other.Foo() : error +>other.Foo : error +>other : typeof other +>Foo : any + +const z = new defaultFoo(); +>z : error +>new defaultFoo() : error +>defaultFoo : error + +=== tests/cases/compiler/other.d.ts === +export interface Foo { + bar: number; +>bar : number +} + +export default interface Bar { + foo: number; +>foo : number +} + +=== tests/cases/compiler/other.js === +export class Foo { +>Foo : Foo + + bar = 2.4; +>bar : number +>2.4 : 2.4 +} + +export default class Bar { +>Bar : Bar + + foo = 1.2; +>foo : number +>1.2 : 1.2 +} + diff --git a/tests/cases/compiler/elidedJSImport.ts b/tests/cases/compiler/elidedJSImport1.ts similarity index 81% rename from tests/cases/compiler/elidedJSImport.ts rename to tests/cases/compiler/elidedJSImport1.ts index 1cf9756660fc5..8709a58a8b65c 100644 --- a/tests/cases/compiler/elidedJSImport.ts +++ b/tests/cases/compiler/elidedJSImport1.ts @@ -1,7 +1,7 @@ // @allowJs: true -// @checkJs: false -// @module: ES2020, commonjs +// @checkJs: true // @moduleResolution: node +// @module: ES2020 // @outDir: out // @Filename: caller.js @@ -13,7 +13,6 @@ console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // // @Filename: node_modules/@truffle/contract/index.d.ts declare module "@truffle/contract" { - // import { ContractObject } from "@truffle/contract-schema"; interface ContractObject { foo: number; } diff --git a/tests/cases/compiler/elidedJSImport2.ts b/tests/cases/compiler/elidedJSImport2.ts index 79ff804743a6e..49cc4d49c7599 100644 --- a/tests/cases/compiler/elidedJSImport2.ts +++ b/tests/cases/compiler/elidedJSImport2.ts @@ -1,8 +1,12 @@ // @allowJs: true // @checkJs: false -// @module: node16 +// @module: ES2022, commonjs +// @moduleResolution: node16 +// @esModuleInterop: true +// @isolatedModules: true // @outDir: out + // @Filename: index.js import { Foo } from "./other.js"; import * as other from "./other.js"; From 3b2c3006b2deebc3ed4fd89da995786e4301b992 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 6 Sep 2022 14:15:01 -0700 Subject: [PATCH 10/13] clean up --- src/compiler/checker.ts | 16 ++------ tests/baselines/reference/elidedJSImport.js | 26 ------------ .../reference/elidedJSImport.symbols | 40 ------------------ .../baselines/reference/elidedJSImport.types | 41 ------------------- 4 files changed, 3 insertions(+), 120 deletions(-) delete mode 100644 tests/baselines/reference/elidedJSImport.js delete mode 100644 tests/baselines/reference/elidedJSImport.symbols delete mode 100644 tests/baselines/reference/elidedJSImport.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2160ea36b2a66..e963a71e73884 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -43076,7 +43076,7 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedSymbol(node, /*startInDeclarationContainer*/ undefined); + const symbol = getReferencedValueOrAliasSymbol(node); // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol @@ -43488,24 +43488,14 @@ namespace ts { * This is because when caching the resolved symbol, we only consider value symbols, but here * we want to also get an alias symbol if one exists. */ - function getReferencedSymbol(reference: Identifier, startInDeclarationContainer?: boolean): Symbol | undefined { + function getReferencedValueOrAliasSymbol(reference: Identifier): Symbol | undefined { const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; if (resolvedSymbol && resolvedSymbol !== unknownSymbol) { return resolvedSymbol; } - let location: Node = reference; - if (startInDeclarationContainer) { - // When resolving the name of a declaration as a value, we need to start resolution - // at a point outside of the declaration. - const parent = reference.parent; - if (isDeclaration(parent) && reference === parent.name) { - location = getDeclarationContainer(parent); - } - } - return resolveName( - location, + reference, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, diff --git a/tests/baselines/reference/elidedJSImport.js b/tests/baselines/reference/elidedJSImport.js deleted file mode 100644 index 72eeecf091216..0000000000000 --- a/tests/baselines/reference/elidedJSImport.js +++ /dev/null @@ -1,26 +0,0 @@ -//// [tests/cases/compiler/elidedJSImport.ts] //// - -//// [caller.js] -import * as fs from 'fs'; -import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform -console.log(fs); -console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' - - -//// [index.d.ts] -declare module "@truffle/contract" { - // import { ContractObject } from "@truffle/contract-schema"; - interface ContractObject { - foo: number; - } - namespace TruffleContract { - export type Contract = ContractObject; - } - export default TruffleContract; -} - -//// [caller.js] -import * as fs from 'fs'; -import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform -console.log(fs); -console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' diff --git a/tests/baselines/reference/elidedJSImport.symbols b/tests/baselines/reference/elidedJSImport.symbols deleted file mode 100644 index 0ad7292e528cb..0000000000000 --- a/tests/baselines/reference/elidedJSImport.symbols +++ /dev/null @@ -1,40 +0,0 @@ -=== tests/cases/compiler/caller.js === -import * as fs from 'fs'; ->fs : Symbol(fs, Decl(caller.js, 0, 6)) - -import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform ->TruffleContract : Symbol(TruffleContract, Decl(caller.js, 1, 6)) - -console.log(fs); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->fs : Symbol(fs, Decl(caller.js, 0, 6)) - -console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) - - -=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === -declare module "@truffle/contract" { ->"@truffle/contract" : Symbol("@truffle/contract", Decl(index.d.ts, 0, 0)) - - // import { ContractObject } from "@truffle/contract-schema"; - interface ContractObject { ->ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) - - foo: number; ->foo : Symbol(ContractObject.foo, Decl(index.d.ts, 2, 30)) - } - namespace TruffleContract { ->TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 4, 5)) - - export type Contract = ContractObject; ->Contract : Symbol(Contract, Decl(index.d.ts, 5, 31)) ->ContractObject : Symbol(ContractObject, Decl(index.d.ts, 0, 36)) - } - export default TruffleContract; ->TruffleContract : Symbol(TruffleContract, Decl(index.d.ts, 4, 5)) -} diff --git a/tests/baselines/reference/elidedJSImport.types b/tests/baselines/reference/elidedJSImport.types deleted file mode 100644 index e706354aa6c9b..0000000000000 --- a/tests/baselines/reference/elidedJSImport.types +++ /dev/null @@ -1,41 +0,0 @@ -=== tests/cases/compiler/caller.js === -import * as fs from 'fs'; ->fs : error - -import TruffleContract from '@truffle/contract'; // Runtime err: this import is elided in transform ->TruffleContract : any - -console.log(fs); ->console.log(fs) : void ->console.log : (...data: any[]) => void ->console : Console ->log : (...data: any[]) => void ->fs : error - -console.log('TruffleContract is ', typeof TruffleContract, TruffleContract); // `TruffleContract` is considered 'unused' ->console.log('TruffleContract is ', typeof TruffleContract, TruffleContract) : void ->console.log : (...data: any[]) => void ->console : Console ->log : (...data: any[]) => void ->'TruffleContract is ' : "TruffleContract is " ->typeof TruffleContract : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" ->TruffleContract : error ->TruffleContract : error - - -=== tests/cases/compiler/node_modules/@truffle/contract/index.d.ts === -declare module "@truffle/contract" { ->"@truffle/contract" : typeof import("@truffle/contract") - - // import { ContractObject } from "@truffle/contract-schema"; - interface ContractObject { - foo: number; ->foo : number - } - namespace TruffleContract { - export type Contract = ContractObject; ->Contract : ContractObject - } - export default TruffleContract; ->TruffleContract : any -} From c2c4fd8dc108438f513c0a7a24127211d59d0119 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 12 Sep 2022 11:23:42 -0700 Subject: [PATCH 11/13] CR: use nameNotFoundMessage to decide whether to report errors in resolveName --- src/compiler/checker.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e963a71e73884..2fc5ea08ae7d5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1827,6 +1827,7 @@ namespace ts { * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with * the given name can be found. * + * @param nameNotFoundMessage If defined, we will report errors found during resolve. * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters. */ function resolveName( @@ -1837,9 +1838,8 @@ namespace ts { nameArg: __String | Identifier | undefined, isUse: boolean, excludeGlobals = false, - getSpellingSuggestions = true, - reportErrors = true): Symbol | undefined { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggestions, getSymbol, reportErrors); + getSpellingSuggestions = true): Symbol | undefined { + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggestions, getSymbol); } function resolveNameHelper( @@ -1851,8 +1851,7 @@ namespace ts { isUse: boolean, excludeGlobals: boolean, getSpellingSuggestions: boolean, - lookup: typeof getSymbol, - reportErrors = true): Symbol | undefined { + lookup: typeof getSymbol): Symbol | undefined { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location let result: Symbol | undefined; let lastLocation: Node | undefined; @@ -2013,7 +2012,7 @@ namespace ts { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. - if (reportErrors) { + if (nameNotFoundMessage) { error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); } return undefined; @@ -2033,7 +2032,7 @@ namespace ts { if (lastLocation === (location as ExpressionWithTypeArguments).expression && (location.parent as HeritageClause).token === SyntaxKind.ExtendsKeyword) { const container = location.parent.parent; if (isClassLike(container) && (result = lookup(getSymbolOfNode(container).members!, name, meaning & SymbolFlags.Type))) { - if (reportErrors && nameNotFoundMessage) { + if (nameNotFoundMessage) { error(errorLocation, Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters); } return undefined; @@ -2053,7 +2052,7 @@ namespace ts { if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) { // A reference to this grandparent's type parameters would be an error if (result = lookup(getSymbolOfNode(grandparent as ClassLikeDeclaration | InterfaceDeclaration).members!, name, meaning & SymbolFlags.Type)) { - if (reportErrors) { + if (nameNotFoundMessage) { error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); } return undefined; @@ -2212,7 +2211,7 @@ namespace ts { } if (!result) { - if (reportErrors && nameNotFoundMessage) { + if (nameNotFoundMessage) { addLazyDiagnostic(() => { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217 @@ -2265,12 +2264,12 @@ namespace ts { } return undefined; } - else if (reportErrors && checkAndReportErrorForInvalidInitializer()) { + else if (nameNotFoundMessage && checkAndReportErrorForInvalidInitializer()) { return undefined; } // Perform extra checks only if error reporting was requested - if (reportErrors && nameNotFoundMessage) { + if (nameNotFoundMessage) { addLazyDiagnostic(() => { // Only check for block-scoped variable if we have an error location and are looking for the // name with variable meaning @@ -43502,8 +43501,7 @@ namespace ts { /*nameArg*/ undefined, /*isUse*/ true, /*excludeGlobals*/ undefined, - /*getSpellingSuggestions*/ undefined, - /*reportErrors*/ false); + /*getSpellingSuggestions*/ undefined); } function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { From 16174c85fe57275f5d06322a84358950490fde43 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 19 Sep 2022 12:14:33 -0700 Subject: [PATCH 12/13] delete unused test and refactor unneeded ternary --- src/compiler/transformers/ts.ts | 5 +- tests/baselines/reference/elidedJSImport2.js | 77 ------------------- .../reference/elidedJSImport2.symbols | 50 ------------ .../baselines/reference/elidedJSImport2.types | 55 ------------- 4 files changed, 2 insertions(+), 185 deletions(-) delete mode 100644 tests/baselines/reference/elidedJSImport2.js delete mode 100644 tests/baselines/reference/elidedJSImport2.symbols delete mode 100644 tests/baselines/reference/elidedJSImport2.types diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 6654b5f52b566..c0bb4ca332b2a 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2463,9 +2463,8 @@ namespace ts { } function shouldEmitAliasDeclaration(node: Node): boolean { - return isInJSFile(node) - ? true - : compilerOptions.preserveValueImports + return isInJSFile(node) || + compilerOptions.preserveValueImports ? resolver.isValueAliasDeclaration(node) : resolver.isReferencedAliasDeclaration(node); } diff --git a/tests/baselines/reference/elidedJSImport2.js b/tests/baselines/reference/elidedJSImport2.js deleted file mode 100644 index 97f1e62b1a840..0000000000000 --- a/tests/baselines/reference/elidedJSImport2.js +++ /dev/null @@ -1,77 +0,0 @@ -//// [tests/cases/compiler/elidedJSImport2.ts] //// - -//// [index.js] -import { Foo } from "./other.js"; -import * as other from "./other.js"; -import defaultFoo from "./other.js"; - -const x = new Foo(); -const y = other.Foo(); -const z = new defaultFoo(); - -//// [other.d.ts] -export interface Foo { - bar: number; -} - -export default interface Bar { - foo: number; -} - -//// [other.js] -export class Foo { - bar = 2.4; -} - -export default class Bar { - foo = 1.2; -} - - -//// [index.js] -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const other_js_1 = require("./other.js"); -const other = __importStar(require("./other.js")); -const other_js_2 = __importDefault(require("./other.js")); -const x = new other_js_1.Foo(); -const y = other.Foo(); -const z = new other_js_2.default(); -//// [other.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Foo = void 0; -class Foo { - bar = 2.4; -} -exports.Foo = Foo; -class Bar { - foo = 1.2; -} -exports.default = Bar; diff --git a/tests/baselines/reference/elidedJSImport2.symbols b/tests/baselines/reference/elidedJSImport2.symbols deleted file mode 100644 index 600c33b51ea6a..0000000000000 --- a/tests/baselines/reference/elidedJSImport2.symbols +++ /dev/null @@ -1,50 +0,0 @@ -=== tests/cases/compiler/index.js === -import { Foo } from "./other.js"; ->Foo : Symbol(Foo, Decl(index.js, 0, 8)) - -import * as other from "./other.js"; ->other : Symbol(other, Decl(index.js, 1, 6)) - -import defaultFoo from "./other.js"; ->defaultFoo : Symbol(defaultFoo, Decl(index.js, 2, 6)) - -const x = new Foo(); ->x : Symbol(x, Decl(index.js, 4, 5)) - -const y = other.Foo(); ->y : Symbol(y, Decl(index.js, 5, 5)) ->other : Symbol(other, Decl(index.js, 1, 6)) - -const z = new defaultFoo(); ->z : Symbol(z, Decl(index.js, 6, 5)) - -=== tests/cases/compiler/other.d.ts === -export interface Foo { ->Foo : Symbol(Foo, Decl(other.d.ts, 0, 0)) - - bar: number; ->bar : Symbol(Foo.bar, Decl(other.d.ts, 0, 22)) -} - -export default interface Bar { ->Bar : Symbol(Bar, Decl(other.d.ts, 2, 1)) - - foo: number; ->foo : Symbol(Bar.foo, Decl(other.d.ts, 4, 30)) -} - -=== tests/cases/compiler/other.js === -export class Foo { ->Foo : Symbol(Foo, Decl(other.js, 0, 0)) - - bar = 2.4; ->bar : Symbol(Foo.bar, Decl(other.js, 0, 18)) -} - -export default class Bar { ->Bar : Symbol(Bar, Decl(other.js, 2, 1)) - - foo = 1.2; ->foo : Symbol(Bar.foo, Decl(other.js, 4, 26)) -} - diff --git a/tests/baselines/reference/elidedJSImport2.types b/tests/baselines/reference/elidedJSImport2.types deleted file mode 100644 index 3fd9545220317..0000000000000 --- a/tests/baselines/reference/elidedJSImport2.types +++ /dev/null @@ -1,55 +0,0 @@ -=== tests/cases/compiler/index.js === -import { Foo } from "./other.js"; ->Foo : any - -import * as other from "./other.js"; ->other : typeof other - -import defaultFoo from "./other.js"; ->defaultFoo : any - -const x = new Foo(); ->x : error ->new Foo() : error ->Foo : error - -const y = other.Foo(); ->y : error ->other.Foo() : error ->other.Foo : error ->other : typeof other ->Foo : any - -const z = new defaultFoo(); ->z : error ->new defaultFoo() : error ->defaultFoo : error - -=== tests/cases/compiler/other.d.ts === -export interface Foo { - bar: number; ->bar : number -} - -export default interface Bar { - foo: number; ->foo : number -} - -=== tests/cases/compiler/other.js === -export class Foo { ->Foo : Foo - - bar = 2.4; ->bar : number ->2.4 : 2.4 -} - -export default class Bar { ->Bar : Bar - - foo = 1.2; ->foo : number ->1.2 : 1.2 -} - From 6a0600d9dc54784751f37bb820e102ea83300078 Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Mon, 19 Sep 2022 12:45:10 -0700 Subject: [PATCH 13/13] add parens --- src/compiler/transformers/ts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index c0bb4ca332b2a..c495d51a2bb30 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2464,9 +2464,9 @@ namespace ts { function shouldEmitAliasDeclaration(node: Node): boolean { return isInJSFile(node) || - compilerOptions.preserveValueImports + (compilerOptions.preserveValueImports ? resolver.isValueAliasDeclaration(node) - : resolver.isReferencedAliasDeclaration(node); + : resolver.isReferencedAliasDeclaration(node)); } } }