mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 20:14:01 -06:00
Added extra restrictions to declaration emit in isolated declaration mode.
This commit is contained in:
parent
e2d5a00c1e
commit
77bdaa2be7
@ -1065,6 +1065,7 @@ import {
|
||||
WideningContext,
|
||||
WithStatement,
|
||||
YieldExpression,
|
||||
isLiteralExpression,
|
||||
} from "./_namespaces/ts";
|
||||
import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers";
|
||||
import * as performance from "./_namespaces/ts.performance";
|
||||
@ -2687,6 +2688,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return symbol;
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Alias) {
|
||||
// Do not take target symbol meaning into account in isolated declaration mode since we don't have access to info from other files.
|
||||
if(compilerOptions.isolatedDeclarations) {
|
||||
return symbol;
|
||||
}
|
||||
const targetFlags = getAllSymbolFlags(symbol);
|
||||
// `targetFlags` will be `SymbolFlags.All` if an error occurred in alias resolution; this avoids cascading errors
|
||||
if (targetFlags & meaning) {
|
||||
@ -46203,7 +46208,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
|
||||
if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) {
|
||||
return isFreshLiteralType(getTypeOfSymbol(getSymbolOfDeclaration(node)));
|
||||
// TODO: isolated declarations: Add a test for this.
|
||||
// In isolated declaration mode we can't really use the freshness of the type as this would require type information.
|
||||
return compilerOptions.isolatedDeclarations?
|
||||
!node.type && !!node.initializer && isLiteralExpression(node.initializer):
|
||||
isFreshLiteralType(getTypeOfSymbol(getSymbolOfDeclaration(node)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ import {
|
||||
hasDynamicName,
|
||||
hasEffectiveModifier,
|
||||
hasExtension,
|
||||
hasIdentifierComputedName,
|
||||
hasJSDocNodes,
|
||||
HasModifiers,
|
||||
hasSyntacticModifier,
|
||||
@ -120,6 +121,7 @@ import {
|
||||
isInterfaceDeclaration,
|
||||
isJsonSourceFile,
|
||||
isLateVisibilityPaintedStatement,
|
||||
isLiteralExpression,
|
||||
isLiteralImportTypeNode,
|
||||
isMappedTypeNode,
|
||||
isMethodDeclaration,
|
||||
@ -317,14 +319,14 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const { noResolve, stripInternal } = options;
|
||||
const isolatedDeclarations = false;
|
||||
const isolatedDeclarations = options.isolatedDeclarations;
|
||||
return transformRoot;
|
||||
|
||||
function reportIsolatedDeclarationError(_node: Node) {
|
||||
// context.addDiagnostic(createDiagnosticForNode(
|
||||
// node,
|
||||
// Diagnostics.Declaration_emit_for_this_file_requires_type_resolution_An_explicit_type_annotation_may_unblock_declaration_emit
|
||||
// ));
|
||||
function reportIsolatedDeclarationError(node: Node) {
|
||||
context.addDiagnostic(createDiagnosticForNode(
|
||||
node,
|
||||
Diagnostics.Declaration_emit_for_this_file_requires_type_resolution_An_explicit_type_annotation_may_unblock_declaration_emit
|
||||
));
|
||||
}
|
||||
function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: readonly [specifier: string, mode: ResolutionMode][] | undefined): void {
|
||||
if (!typeReferenceDirectives) {
|
||||
@ -584,7 +586,8 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
combinedStatements = setTextRange(factory.createNodeArray([...combinedStatements, createEmptyExports(factory)]), combinedStatements);
|
||||
}
|
||||
}
|
||||
const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
|
||||
const typeReferences = isolatedDeclarations? node.typeReferenceDirectives: getFileReferencesForUsedTypeReferences();
|
||||
const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, typeReferences, node.hasNoDefaultLib, getLibReferences());
|
||||
updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
|
||||
return updated;
|
||||
|
||||
@ -704,7 +707,9 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (elem.kind === SyntaxKind.OmittedExpression) {
|
||||
return elem;
|
||||
}
|
||||
if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced && !isIdentifierANonContextualKeyword(elem.propertyName)) {
|
||||
if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name)
|
||||
// TODO: isolated declarations: find a better way for this since we don't actually do signature usage analysis
|
||||
&& !isolatedDeclarations&& !elem.symbol.isReferenced && !isIdentifierANonContextualKeyword(elem.propertyName)) {
|
||||
// Unnecessary property renaming is forbidden in types, so remove renaming
|
||||
return factory.updateBindingElement(
|
||||
elem,
|
||||
@ -746,12 +751,14 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
}
|
||||
|
||||
function shouldPrintWithInitializer(node: Node) {
|
||||
if (isolatedDeclarations) return false;
|
||||
return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe
|
||||
}
|
||||
|
||||
function ensureNoInitializer(node: CanHaveLiteralInitializer) {
|
||||
if (shouldPrintWithInitializer(node)) {
|
||||
if(node.initializer && isLiteralExpression(node.initializer)) {
|
||||
return node.initializer;
|
||||
}
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe
|
||||
}
|
||||
return undefined;
|
||||
@ -898,7 +905,10 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (!isPrivate) {
|
||||
const valueParameter = getSetAccessorValueParameter(input);
|
||||
if (valueParameter) {
|
||||
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
|
||||
const accessorType =
|
||||
isolatedDeclarations ?
|
||||
undefined:
|
||||
getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
|
||||
newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType);
|
||||
}
|
||||
}
|
||||
@ -1034,6 +1044,12 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
}
|
||||
// Augmentation of export depends on import
|
||||
if (resolver.isImportRequiredByAugmentation(decl)) {
|
||||
if(isolatedDeclarations) {
|
||||
// TODO: Should report better error here. Suggest we add the syntax import type '....'
|
||||
// Also add a test for this.
|
||||
reportIsolatedDeclarationError(decl)
|
||||
return undefined;
|
||||
}
|
||||
return factory.updateImportDeclaration(
|
||||
decl,
|
||||
decl.modifiers,
|
||||
@ -1114,7 +1130,11 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (isDeclaration(input)) {
|
||||
if (isDeclarationAndNotVisible(input)) return;
|
||||
if (hasDynamicName(input) && !resolver.isLateBound(getParseTreeNode(input) as Declaration)) {
|
||||
return;
|
||||
if (hasIdentifierComputedName(input)) {
|
||||
reportIsolatedDeclarationError(input);
|
||||
}else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1208,7 +1228,10 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (isPrivateIdentifier(input.name)) {
|
||||
return cleanup(/*returnValue*/ undefined);
|
||||
}
|
||||
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
|
||||
const accessorType =
|
||||
isolatedDeclarations ?
|
||||
input.type:
|
||||
getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
|
||||
return cleanup(factory.updateGetAccessorDeclaration(
|
||||
input,
|
||||
ensureModifiers(input),
|
||||
@ -1406,7 +1429,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
reportIsolatedDeclarationError(input);
|
||||
}
|
||||
const type = isolatedDeclarations ?
|
||||
factory.createTypeReferenceNode("invalud") :
|
||||
factory.createTypeReferenceNode("invalid") :
|
||||
resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker)
|
||||
const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, type, /*initializer*/ undefined);
|
||||
errorFallbackNode = undefined;
|
||||
@ -1502,7 +1525,12 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
ensureType(input, input.type),
|
||||
/*body*/ undefined
|
||||
));
|
||||
if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
|
||||
const isExpandoFunctionDeclaration = clean && resolver.isExpandoFunctionDeclaration(input);
|
||||
if (isExpandoFunctionDeclaration && shouldEmitFunctionProperties(input)) {
|
||||
if(isExpandoFunctionDeclaration && isolatedDeclarations) {
|
||||
reportIsolatedDeclarationError(input);
|
||||
return clean;
|
||||
}
|
||||
const props = resolver.getPropertiesOfContainerFunction(input);
|
||||
// Use parseNodeFactory so it is usable as an enclosing declaration
|
||||
const fakespace = parseNodeFactory.createModuleDeclaration(/*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace);
|
||||
@ -1830,8 +1858,9 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node);
|
||||
}
|
||||
errorNameNode = (node as NamedDeclaration).name;
|
||||
Debug.assert(resolver.isLateBound(getParseTreeNode(node) as Declaration)); // Should only be called with dynamic names
|
||||
const decl = node as NamedDeclaration as LateBoundDeclaration;
|
||||
|
||||
Debug.assert((hasIdentifierComputedName(decl) && options.isolatedDeclarations) || resolver.isLateBound(getParseTreeNode(node) as Declaration)); // Should only be called with dynamic names
|
||||
const entityName = decl.name.expression;
|
||||
checkEntityNameVisibility(entityName, enclosingDeclaration);
|
||||
if (!suppressNewDiagnosticContexts) {
|
||||
|
||||
@ -4897,6 +4897,27 @@ export function isDynamicName(name: DeclarationName): boolean {
|
||||
!isSignedNumericLiteral(expr);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function hasIdentifierComputedName(declaration: Declaration): declaration is DynamicNamedDeclaration | DynamicNamedBinaryExpression {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
return !!name && isIdentifierComputedName(name);
|
||||
}
|
||||
/** @internal */
|
||||
export function isIdentifierComputedName(name: DeclarationName): boolean {
|
||||
if (!(name.kind === SyntaxKind.ComputedPropertyName || name.kind === SyntaxKind.ElementAccessExpression)) {
|
||||
return false;
|
||||
}
|
||||
let expr = isElementAccessExpression(name) ? skipParentheses(name.argumentExpression) : name.expression;
|
||||
while(isPropertyAccessExpression(expr)) {
|
||||
expr = expr.expression;
|
||||
}
|
||||
return isIdentifier(expr);
|
||||
}
|
||||
|
||||
|
||||
/** @internal */
|
||||
export function getPropertyNameForPropertyNameNode(name: PropertyName): __String | undefined {
|
||||
switch (name.kind) {
|
||||
|
||||
@ -62,5 +62,5 @@ export = K;
|
||||
import K = require('./k');
|
||||
K.One;
|
||||
|
||||
// @Filename: /j.ts
|
||||
// @Filename: /m.ts
|
||||
// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207
|
||||
Loading…
x
Reference in New Issue
Block a user