Check the ambientness of a symbol name before attempting to trim it (#26312)

* Check the ambientness of a symbol name before attempting to trim it

* Use find instead of forEach, remember to also exclude global augmentations
This commit is contained in:
Wesley Wigham 2018-08-09 13:20:37 -07:00 committed by GitHub
parent f6af618ab9
commit fce3d9f34d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 272 additions and 45 deletions

View file

@ -3880,31 +3880,34 @@ namespace ts {
}
}
}
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
}
else {
if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
// If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) {
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
}
const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration));
const links = getSymbolLinks(symbol);
let specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
if (!specifier) {
specifier = moduleSpecifiers.getModuleSpecifierForDeclarationFile(
symbol,
compilerOptions,
contextFile,
context.tracker.moduleResolverHost,
context.tracker.moduleResolverHost.getSourceFiles!(), // TODO: GH#18217
{ importModuleSpecifierPreference: "non-relative" },
host.redirectTargetsMap,
);
links.specifierCache = links.specifierCache || createMap();
links.specifierCache.set(contextFile.path, specifier);
}
return specifier;
}
if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
// If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) {
return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1);
}
return getSourceFileOfNode(getNonAugmentationDeclaration(symbol)!).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full
}
const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration));
const links = getSymbolLinks(symbol);
let specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
if (!specifier) {
specifier = moduleSpecifiers.getModuleSpecifierForDeclarationFile(
symbol,
compilerOptions,
contextFile,
context.tracker.moduleResolverHost,
context.tracker.moduleResolverHost.getSourceFiles!(), // TODO: GH#18217
{ importModuleSpecifierPreference: "non-relative" },
host.redirectTargetsMap,
);
links.specifierCache = links.specifierCache || createMap();
links.specifierCache.set(contextFile.path, specifier);
}
return specifier;
}
function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: ReadonlyArray<TypeNode>): TypeNode {

View file

@ -51,7 +51,7 @@ namespace ts.moduleSpecifiers {
if (!files) {
return Debug.fail("Files list must be present to resolve symlinks in specifier resolution");
}
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration);
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions));
@ -232,8 +232,10 @@ namespace ts.moduleSpecifiers {
}
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
const decl = moduleSymbol.valueDeclaration;
if (isModuleDeclaration(decl) && isStringLiteral(decl.name)) {
const decl = find(moduleSymbol.declarations,
d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name)))
) as (ModuleDeclaration & { name: StringLiteral }) | undefined;
if (decl) {
return decl.name.text;
}
}

View file

@ -638,6 +638,10 @@ namespace ts {
return false;
}
export function getNonAugmentationDeclaration(symbol: Symbol) {
return find(symbol.declarations, d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d)));
}
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
}

View file

@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
function foo() {}
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.ts")
export var v = 1;
>v : number

View file

@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : typeof import("file1")
function foo(): void;
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.d.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.d.ts")
export var v: number;
>v : number

View file

@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
class foo {}
>foo : import("o")
>foo : import("tests/cases/compiler/file1.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.ts")
export var v = 1;
>v : number

View file

@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : typeof import("file1")
class foo {}
>foo : import("o")
>foo : import("tests/cases/compiler/file1.d.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.d.ts")
export var v: number;
>v : number

View file

@ -9,11 +9,11 @@ declare module "express" {
>"express" : typeof import("express")
function e(): e.Express;
>e : typeof import("e")
>e : typeof import("tests/cases/compiler/express.d.ts")
>e : any
namespace e {
>e : typeof import("e")
>e : typeof import("tests/cases/compiler/express.d.ts")
interface IRoute {
all(...handler: RequestHandler[]): IRoute;

View file

@ -1,9 +1,9 @@
=== tests/cases/compiler/file1.ts ===
class foo {}
>foo : import("o")
>foo : import("tests/cases/compiler/file1.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.ts")
export class A {}
>A : A

View file

@ -3,10 +3,10 @@ declare module "file1" {
>"file1" : typeof import("file1")
class foo {}
>foo : import("o")
>foo : import("tests/cases/compiler/file1.d.ts")
namespace foo {
>foo : typeof import("o")
>foo : typeof import("tests/cases/compiler/file1.d.ts")
class A {}
>A : A

View file

@ -6,7 +6,7 @@ import moment = require("moment-timezone");
=== tests/cases/compiler/node_modules/moment/index.d.ts ===
declare function moment(): moment.Moment;
>moment : () => import("omen").Moment
>moment : () => import("tests/cases/compiler/node_modules/moment/index.d.ts").Moment
>moment : any
declare namespace moment {
@ -16,7 +16,7 @@ declare namespace moment {
}
}
export = moment;
>moment : () => import("omen").Moment
>moment : () => import("tests/cases/compiler/node_modules/moment/index.d.ts").Moment
=== tests/cases/compiler/node_modules/moment-timezone/index.d.ts ===
import * as moment from 'moment';

View file

@ -0,0 +1,49 @@
//// [tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts] ////
//// [index.d.ts]
declare namespace React {
export interface DetailedHTMLProps<T, U> {}
export interface HTMLAttributes<T> {}
}
export = React;
export as namespace React;
//// [index.d.ts]
/// <reference types="react" />
declare module 'react' { // augment
interface HTMLAttributes<T> {
css?: unknown;
}
}
export interface StyledOtherComponentList {
"div": React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
}
export interface StyledOtherComponent<A, B, C> {}
//// [index.d.ts]
export * from "./types/react";
//// [index.d.ts]
import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled";
export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>;
//// [index.ts]
import styled from "react-emotion"
const Form = styled('div')({ color: "red" })
export default Form
//// [index.js]
"use strict";
exports.__esModule = true;
var react_emotion_1 = require("react-emotion");
var Form = react_emotion_1["default"]('div')({ color: "red" });
exports["default"] = Form;
//// [index.d.ts]
/// <reference path="node_modules/create-emotion-styled/types/react/index.d.ts" />
/// <reference types="react" />
declare const Form: import("create-emotion-styled/types/react").StyledOtherComponent<{}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>;
export default Form;

View file

@ -0,0 +1,77 @@
=== tests/cases/compiler/node_modules/react/index.d.ts ===
declare namespace React {
>React : Symbol(React, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 0))
export interface DetailedHTMLProps<T, U> {}
>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 0, 25))
>T : Symbol(T, Decl(index.d.ts, 1, 39))
>U : Symbol(U, Decl(index.d.ts, 1, 41))
export interface HTMLAttributes<T> {}
>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24))
>T : Symbol(T, Decl(index.d.ts, 2, 36), Decl(index.d.ts, 2, 29))
}
export = React;
>React : Symbol(React, Decl(index.d.ts, 0, 0))
export as namespace React;
>React : Symbol(React, Decl(index.d.ts, 4, 15))
=== tests/cases/compiler/node_modules/create-emotion-styled/types/react/index.d.ts ===
/// <reference types="react" />
declare module 'react' { // augment
>'react' : Symbol(React, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 0))
interface HTMLAttributes<T> {
>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24))
>T : Symbol(T, Decl(index.d.ts, 2, 36), Decl(index.d.ts, 2, 29))
css?: unknown;
>css : Symbol(HTMLAttributes.css, Decl(index.d.ts, 2, 33))
}
}
export interface StyledOtherComponentList {
>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 5, 1))
"div": React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
>"div" : Symbol(StyledOtherComponentList["div"], Decl(index.d.ts, 6, 43))
>React : Symbol(React, Decl(index.d.ts, 4, 15))
>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 0, 25))
>React : Symbol(React, Decl(index.d.ts, 4, 15))
>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24))
>HTMLDivElement : Symbol(HTMLDivElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>HTMLDivElement : Symbol(HTMLDivElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
}
export interface StyledOtherComponent<A, B, C> {}
>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 8, 1))
>A : Symbol(A, Decl(index.d.ts, 9, 38))
>B : Symbol(B, Decl(index.d.ts, 9, 40))
>C : Symbol(C, Decl(index.d.ts, 9, 43))
=== tests/cases/compiler/node_modules/create-emotion-styled/index.d.ts ===
export * from "./types/react";
No type information for this code.
No type information for this code.=== tests/cases/compiler/node_modules/react-emotion/index.d.ts ===
import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled";
>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 0, 8))
>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 0, 29))
export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>;
>styled : Symbol(styled, Decl(index.d.ts, 0, 85))
>tag : Symbol(tag, Decl(index.d.ts, 1, 31))
>o : Symbol(o, Decl(index.d.ts, 1, 46))
>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 0, 8))
>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 0, 29))
=== tests/cases/compiler/index.ts ===
import styled from "react-emotion"
>styled : Symbol(styled, Decl(index.ts, 0, 6))
const Form = styled('div')({ color: "red" })
>Form : Symbol(Form, Decl(index.ts, 2, 5))
>styled : Symbol(styled, Decl(index.ts, 0, 6))
>color : Symbol(color, Decl(index.ts, 2, 28))
export default Form
>Form : Symbol(Form, Decl(index.ts, 2, 5))

View file

@ -0,0 +1,59 @@
=== tests/cases/compiler/node_modules/react/index.d.ts ===
declare namespace React {
export interface DetailedHTMLProps<T, U> {}
export interface HTMLAttributes<T> {}
}
export = React;
>React : any
export as namespace React;
>React : any
=== tests/cases/compiler/node_modules/create-emotion-styled/types/react/index.d.ts ===
/// <reference types="react" />
declare module 'react' { // augment
>'react' : any
interface HTMLAttributes<T> {
css?: unknown;
>css : unknown
}
}
export interface StyledOtherComponentList {
"div": React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
>"div" : import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>
>React : any
>React : any
}
export interface StyledOtherComponent<A, B, C> {}
=== tests/cases/compiler/node_modules/create-emotion-styled/index.d.ts ===
export * from "./types/react";
No type information for this code.
No type information for this code.=== tests/cases/compiler/node_modules/react-emotion/index.d.ts ===
import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled";
>StyledOtherComponent : any
>StyledOtherComponentList : any
export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>;
>styled : (tag: string) => (o: object) => StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
>tag : string
>o : object
=== tests/cases/compiler/index.ts ===
import styled from "react-emotion"
>styled : (tag: string) => (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
const Form = styled('div')({ color: "red" })
>Form : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
>styled('div')({ color: "red" }) : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
>styled('div') : (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
>styled : (tag: string) => (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>
>'div' : "div"
>{ color: "red" } : { color: string; }
>color : string
>"red" : "red"
export default Form
>Form : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps<import("tests/cases/compiler/node_modules/react/index.d.ts").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, any>

View file

@ -46,13 +46,13 @@ var t = p.x;
=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts ===
export as namespace Math2d;
>Math2d : typeof import("2")
>Math2d : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts")
export = M2D;
>M2D : typeof M2D
declare namespace M2D {
>M2D : typeof import("2")
>M2D : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts")
interface Point {
x: number;

View file

@ -44,13 +44,13 @@ var t = p.x;
=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts ===
export as namespace Math2d;
>Math2d : typeof import("2")
>Math2d : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts")
export = M2D;
>M2D : typeof M2D
declare namespace M2D {
>M2D : typeof import("2")
>M2D : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts")
interface Point {
x: number;

View file

@ -0,0 +1,33 @@
// @declaration: true
// @filename: node_modules/react/index.d.ts
declare namespace React {
export interface DetailedHTMLProps<T, U> {}
export interface HTMLAttributes<T> {}
}
export = React;
export as namespace React;
// @filename: node_modules/create-emotion-styled/types/react/index.d.ts
/// <reference types="react" />
declare module 'react' { // augment
interface HTMLAttributes<T> {
css?: unknown;
}
}
export interface StyledOtherComponentList {
"div": React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
}
export interface StyledOtherComponent<A, B, C> {}
// @filename: node_modules/create-emotion-styled/index.d.ts
export * from "./types/react";
// @filename: node_modules/react-emotion/index.d.ts
import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled";
export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>;
// @filename: index.ts
import styled from "react-emotion"
const Form = styled('div')({ color: "red" })
export default Form