Skip to content

Commit

Permalink
Resolve correctly exported type aliases
Browse files Browse the repository at this point in the history
see #270
see #299
  • Loading branch information
Schahen committed Jun 3, 2020
1 parent 7cfe6f9 commit a111778
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 46 deletions.
4 changes: 4 additions & 0 deletions compiler/test/data/typescript/import/typeAlias/_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

export type Environment = 'production' | 'development';

export type DefaultPorts = 80 | 440;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "EXTERNAL_DELEGATION")

import kotlin.js.*
import kotlin.js.Json
import org.khronos.webgl.*
import org.w3c.dom.*
import org.w3c.dom.events.*
import org.w3c.dom.parsing.*
import org.w3c.dom.svg.*
import org.w3c.dom.url.*
import org.w3c.fetch.*
import org.w3c.files.*
import org.w3c.notifications.*
import org.w3c.performance.*
import org.w3c.workers.*
import org.w3c.xhr.*

external interface State {
var currentEnvironment: String /* 'production' | 'development' */
fun ping(port: Number /* 80 | 440 */)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {DefaultPorts, Environment} from './_api';

export interface State {
currentEnvironment: Environment;
ping(port: DefaultPorts);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ external open class C : A {
override fun ping(a: String)
}

external open class D : A {
external open class D : B {
open fun ping(d: Any)
override fun ping(a: String)
}
Expand Down
17 changes: 7 additions & 10 deletions typescript/ts-converter/src/AstConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import {AstFactory} from "./ast/AstFactory";
import {DeclarationResolver} from "./DeclarationResolver";
import {AstExpressionConverter} from "./ast/AstExpressionConverter";
import {ExportContext} from "./ExportContext";
import {ExportContext, resolveDeclarations} from "./ExportContext";
import {tsInternals} from "./TsInternals";
import {
CaseDeclarationProto,
Expand Down Expand Up @@ -404,16 +404,13 @@ export class AstConverter {
}

private createUid(identifier: ts.Identifier): string | null {
let typeOfSymbol = this.typeChecker.getDeclaredTypeOfSymbol(this.typeChecker.getSymbolAtLocation(identifier));
let uid: string | null = null;
if (typeOfSymbol && typeOfSymbol.symbol && Array.isArray(typeOfSymbol.symbol.declarations)) {
let declarationFromSymbol = typeOfSymbol.symbol.declarations[0];
//TODO: encountered in @types/express, need to work on a separate test case
let uidContext = (declarationFromSymbol.parent && ts.isTypeAliasDeclaration(declarationFromSymbol.parent)) ?
declarationFromSymbol.parent : declarationFromSymbol;
uid = this.exportContext.getUID(uidContext);
let declarations = resolveDeclarations(identifier, this.typeChecker);

if (declarations[0]) {
return this.exportContext.getUID(declarations[0]);
}
return uid;

return null;
}

private createTypeReferenceFromSymbol(declaration: ts.Declaration | null): ReferenceEntity | null {
Expand Down
37 changes: 2 additions & 35 deletions typescript/ts-converter/src/DependencyBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
TranslateAllSymbolsDependency,
TranslateSubsetOfSymbolsDependency
} from "./Dependency";
import {resolveDeclarations} from "./ExportContext";

export class DependencyBuilder {
private dependencies = new Map<string, Dependency>();
Expand Down Expand Up @@ -53,42 +54,8 @@ export class DependencyBuilder {
) {
}

private getDeclarations(node: ts.Node): Array<ts.Node> {
let symbolAtLocation = this.typeChecker.getSymbolAtLocation(node);
if (symbolAtLocation) {

if (symbolAtLocation.flags & ts.SymbolFlags.Alias) {
let aliasedSymbol = this.typeChecker.getAliasedSymbol(symbolAtLocation);
if (aliasedSymbol && Array.isArray(aliasedSymbol.declarations)) {
return aliasedSymbol.declarations;
} else {
return [];
}
}

if (Array.isArray(symbolAtLocation.declarations)) {
return symbolAtLocation.declarations;
} else {
let declaredTyped = this.typeChecker.getDeclaredTypeOfSymbol(symbolAtLocation);
if (declaredTyped) {
let resolvedASymbol = declaredTyped.symbol || declaredTyped.aliasSymbol;
if (resolvedASymbol && Array.isArray(resolvedASymbol.declarations)) {
return resolvedASymbol.declarations;
}
}
}
}

let symbol = this.typeChecker.getTypeAtLocation(node).symbol;
if (symbol && Array.isArray(symbol.declarations)) {
return symbol.declarations;
}

return [];
}

private checkReferences(node: ts.Node) {
let declarations = this.getDeclarations(node);
let declarations = resolveDeclarations(node, this.typeChecker);

for (let declaration of declarations) {
if (this.checkedReferences.has(declaration)) {
Expand Down
34 changes: 34 additions & 0 deletions typescript/ts-converter/src/ExportContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,40 @@ function resolveName(node: ts.Node): string | null {
return null;
}

export function resolveDeclarations(node: ts.Identifier, typeChecker: ts.TypeChecker): Array<ts.Node> {
let symbolAtLocation = typeChecker.getSymbolAtLocation(node);
if (symbolAtLocation) {

if (symbolAtLocation.flags & ts.SymbolFlags.Alias) {
let aliasedSymbol = typeChecker.getAliasedSymbol(symbolAtLocation);
if (aliasedSymbol && Array.isArray(aliasedSymbol.declarations)) {
return aliasedSymbol.declarations;
} else {
return [];
}
}

if (Array.isArray(symbolAtLocation.declarations)) {
return symbolAtLocation.declarations;
} else {
let declaredTyped = typeChecker.getDeclaredTypeOfSymbol(symbolAtLocation);
if (declaredTyped) {
let resolvedASymbol = declaredTyped.symbol || declaredTyped.aliasSymbol;
if (resolvedASymbol && Array.isArray(resolvedASymbol.declarations)) {
return resolvedASymbol.declarations;
}
}
}
}

let symbol = typeChecker.getTypeAtLocation(node).symbol;
if (symbol && Array.isArray(symbol.declarations)) {
return symbol.declarations;
}

return [];
}

export class ExportContext {
private exportTable: Map<ts.Node, string> = new Map();
private log = createLogger("ExportContext");
Expand Down

0 comments on commit a111778

Please sign in to comment.