Skip to content

Another try to not use namespace #39344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
29 changes: 29 additions & 0 deletions NoNameSpace/.vscode/launch.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Current TS File",
"type": "node",
"request": "launch",
"args": [
"${relativeFile}"
],
"runtimeArgs": [
"--nolazy",
"-r",
"ts-node/register"
],
"sourceMaps": true,
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json"
}
}
]
}
4 changes: 4 additions & 0 deletions NoNameSpace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1. rename many symbol to avoid conflict, all renamed are added "NamespaceLocal"
2. remove deep namespace property

3. how to merge namespace?
35 changes: 35 additions & 0 deletions NoNameSpace/continueRemoveNamespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { walkFolder, tsMatch, srcFolder } from ".";
import fs from "fs";
import readline from "readline";

async function fileCB(filePath: string) {
const fileStream = fs.createReadStream(filePath);

const rl = readline.createInterface({
input: fileStream,
// crlfDelay: Infinity
});
let newFileContent = "";
let removeNamespaceFlag = false;
for await (const line of rl) {
const namespaceRE = RegExp("^(declare )?namespace .*?\\{$");
const namespaceEndRE = RegExp("^\\}$");
// const noNamespaceTsdotRE = /(?<!namespace)(\W)ts\./g;
if (namespaceRE.test(line)) {
//skip, not output
removeNamespaceFlag = true;
}
else if (namespaceEndRE.test(line)) {
if (!removeNamespaceFlag) {
newFileContent += line;
}
}
else {
newFileContent += line;
}
newFileContent += "\r\n";
}
fs.writeFile(filePath, newFileContent, () => { });
}

walkFolder(srcFolder, tsMatch, fileCB);
100 changes: 100 additions & 0 deletions NoNameSpace/createNamespaceLikeFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// import readline from "readline";
import fs from "fs";
import path from "path";
import { srcFolder } from ".";
import namespaceInfo from './namespacePath.json';

/**
* namespace name: {position:,times:}
*/

const namespaceLikeFilesFolderPath = path.resolve(srcFolder, "namespaceLike");
if (!fs.existsSync(namespaceLikeFilesFolderPath)) {
fs.mkdirSync(namespaceLikeFilesFolderPath);
}

function getRelativePathFromAbsolutePath(filePath: string) {
const relativePath = filePath.replace(/^.*?src\\/, "../").replace(/\\/g, "/").slice(0, -3);
return relativePath;
}

/**
*
* @param filePath
* @param rename rename is for optimise
*/
function createFirstLevel(relativePath: string, rename?: string) {
let result = "";
result += "\r\n";
result += `export *${rename ? ` as ${rename}` : ""} from "${relativePath}";`;
return result;
}

function createSecondLevel(relativePath: string, rename: string) {
let result = "";
result += "\r\n";
result += `import * as ${rename} from "${relativePath}"`;
result += "\r\n";
result += `export {${rename}}`;
return result;
}

// delete namespaceInfo.A;
// delete namespaceInfo.Foo;
// delete namespaceInfo.normalN;
// delete namespaceInfo.M;
// delete namespaceInfo.myapp;

function main(namespaceInfo: { [namespacePath: string]: { [filePath: string]: number } }) {
const namespaceNames = Object.keys(namespaceInfo);
namespaceNames.forEach(n => {
const namespacePathAccess = n.split(".");
let fileContent = "";
if (namespacePathAccess.length === 1) {
const namespaceFilePaths = namespaceInfo[n];
Object.keys(namespaceFilePaths).forEach(nfp => {
fileContent += createFirstLevel(getRelativePathFromAbsolutePath(nfp));
});
const nextNamespacePaths = namespaceNames.filter(nsn => RegExp(`${n.replace("/\./g", "\\.")}\\.(?!\\w+\\.)`).test(nsn));
nextNamespacePaths.forEach((nnp) => {
const afterNamespacePaths = namespaceNames.filter(nsn => RegExp(`${nnp.replace("/\./g", "\\.")}\\.`).test(nsn));
if (Object.keys(namespaceInfo[nnp]).length > 1 || afterNamespacePaths.length > 1) {
fileContent += createSecondLevel("./" + nnp, nnp.split(".").pop()!);
} else {
const theFilePath = Object.keys(namespaceInfo[nnp])[0];
fileContent += createFirstLevel(getRelativePathFromAbsolutePath(theFilePath), nnp.split(".").pop());
}
});
} else {
const namespaceFilePaths = namespaceInfo[n];
let skipFlag1 = false;
let skipFlag2 = false;

if (Object.keys(namespaceFilePaths).length === 1) {
skipFlag1 = true;
}
Object.keys(namespaceFilePaths).forEach(nfp => {
fileContent += createFirstLevel(getRelativePathFromAbsolutePath(nfp));
});
const nextNamespacePaths = namespaceNames.filter(nt => RegExp(`${n.replace("/\./g", "\\.")}\\.(?!\\w+\\.)`).test(nt));
if (nextNamespacePaths.length === 0) {
skipFlag2 = true;
}
nextNamespacePaths.forEach((nnp) => {
const afterNamespacePaths = namespaceNames.filter(nsn => RegExp(`${nnp.replace("/\./g", "\\.")}\\.`).test(nsn));
if (Object.keys(namespaceInfo[nnp]).length > 1 || afterNamespacePaths.length > 1) {
fileContent += createSecondLevel("./" + nnp, nnp.split(".").pop()!);
} else {
const theFilePath = Object.keys(namespaceInfo[nnp])[0];
fileContent += createFirstLevel(getRelativePathFromAbsolutePath(theFilePath), nnp.split(".").pop());
}
});
if (skipFlag1 && skipFlag2) {
return;
}
}
fs.writeFile(path.resolve(namespaceLikeFilesFolderPath, n + ".ts"), fileContent, () => { });
});
}

main(namespaceInfo);
89 changes: 89 additions & 0 deletions NoNameSpace/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@

/**
* steps to remove namespace
* 1. remove namespaces in all ts files in src/*.
* 2. use add all missing imports to auto-fix
*/

/**
* Details about step1:
* 1. ts.A.B
* 1. ts.A.B
* 2. namespace merge like partial keyword in c#
* 3.
*/
import readline from "readline";
import path from "path";
import fs from "fs";

export const srcFolder = path.resolve(__dirname, "../src");

export async function walkFolder(filePath: string, match: (s: string) => boolean, fileCallback: (s: string) => void, finalCallback?: () => void) {
let counter = 0;
return (async function walker(filePath: string, match: (s: string) => boolean, fileCallback: (s: string) => void) {
counter = counter + 1;
const isDirectory = fs.lstatSync(filePath).isDirectory();
if (!isDirectory) {
if (match(filePath)) {
await fileCallback(filePath);
}
}
else {
const subFileNames = fs.readdirSync(filePath);
subFileNames.forEach(subFileName => walker(path.resolve(filePath, subFileName), match, fileCallback));
}
counter = counter - 1;
if (counter === 0) {
if (finalCallback){
finalCallback();
}
}

})(filePath, match, fileCallback);
}

async function fileCB(filePath: string) {
const fileStream = fs.createReadStream(filePath);

const rl = readline.createInterface({
input: fileStream,
// crlfDelay: Infinity
});
let newFileContent = "";
let removeNamespaceFlag = false;
for await (const line of rl) {
const namespaceRE = RegExp("^(declare )?namespace .*?\\{$");
// const namespaceTsRE = RegExp("^(declare )?namespace ts \\{$");
const namespaceEndRE = RegExp("^\\}$");
// const noNamespaceTsdotRE = /(?<!namespace)(\W)ts\./g;
const tsdotRE = /(\W)ts\./g;
if (namespaceRE.test(line)) {
//skip, not output
removeNamespaceFlag = true;
}
else if (tsdotRE.test(line)) {
const newline = line.replace(tsdotRE, "$1");
newFileContent += newline;
}
else if (namespaceEndRE.test(line)) {
if (!removeNamespaceFlag) {
newFileContent += line;
}
}
else {
newFileContent += line;
}
newFileContent += "\r\n";
}
fs.writeFile(filePath, newFileContent, () => { });
}

export function tsMatch(filepath: string) {
const tsAndNotDeclaration = RegExp("(?<!\\.d)\\.ts");
if (tsAndNotDeclaration.test(filepath)) {
return true;
}
return false;
}

walkFolder(srcFolder, tsMatch, fileCB);
Loading