Skip to content

Commit

Permalink
innerDep contain the exports module
Browse files Browse the repository at this point in the history
  • Loading branch information
peze committed Dec 6, 2024
1 parent 427cc1d commit 9ae3fb0
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 5 deletions.
43 changes: 39 additions & 4 deletions lib/semantic.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const {

const builtin = require('./builtin');

const existsChecker = new Map();

function replace(origin, target) {
Object.keys(origin).forEach((key) => {
delete origin[key];
Expand Down Expand Up @@ -507,6 +509,7 @@ class TypeChecker {
} else {
this.libraries = libraries;
}
existsChecker.set(filename, this);
}

error(message, token) {
Expand Down Expand Up @@ -567,6 +570,7 @@ class TypeChecker {
});

find = checker.findProperty(extendModel, propName, isException, moduleName, extendFrom);

if(!find) {
return;
}
Expand Down Expand Up @@ -744,7 +748,7 @@ class TypeChecker {
const item = ast.imports[i];
const aliasId = item.lexeme;

const innerModule = !!item.innerPath;
let innerModule = !!item.innerPath;
const mainModule = item.mainModule;

if (!mainModule && !innerModule && !pkg.libraries[aliasId] && pkg.name !== aliasId) {
Expand Down Expand Up @@ -776,6 +780,7 @@ class TypeChecker {
this.error(`the submodule id "${module}" has not been exported in "${mainModule}"`, item);
}
realSpecPath = path.join(libPath, libMeta.exports[module]);
innerModule = true;
} else if(innerModule) {
if (item.innerPath.endsWith('.dara') || item.innerPath.endsWith('.tea') || item.innerPath.endsWith('.spec')) {
realSpecPath = path.join(pkgDir, item.innerPath);
Expand Down Expand Up @@ -808,7 +813,7 @@ class TypeChecker {
const lexer = new Lexer(source, realSpecPath);
const parser = new Parser(lexer);
const depAst = parser.program();
const checker = new TypeChecker(source, realSpecPath, this.root, this.libraries, innerModule).check(depAst);
const checker = existsChecker.get(realSpecPath) || new TypeChecker(source, realSpecPath, this.root, this.libraries, innerModule).check(depAst);
this.dependencies.set(aliasId, checker);
if(innerModule) {
this.innerDep.set(aliasId, checker.ast);
Expand All @@ -817,6 +822,34 @@ class TypeChecker {
}
}

checkExports(){
const filePath = this.filename;
const pkgDir = path.dirname(filePath);
const pkgPath = this.inner ? getDarafile(this.root) : getDarafile(pkgDir);
if (!fs.existsSync(pkgPath)) {
return;
}

const pkg = JSON.parse(stripComments(fs.readFileSync(pkgPath, 'utf-8')));
if(!pkg.exports) {
return;
}
const exports = Object.keys(pkg.exports);
for (let i = 0; i < exports.length; i++) {
const aliasId = exports[i];
if(this.innerDep.has(aliasId)) {
continue;
}
const exportSpec = path.join(pkgDir, pkg.exports[aliasId]);
const source = fs.readFileSync(exportSpec, 'utf-8');
const lexer = new Lexer(source, exportSpec);
const parser = new Parser(lexer);
const depAst = parser.program();
const checker = existsChecker.get(exportSpec) || new TypeChecker(source, exportSpec, this.root, this.libraries, true).check(depAst);
this.innerDep.set(aliasId, checker.ast);
}
}

check(ast) {
assert.equal(ast.type, 'module');
// 类型系统
Expand Down Expand Up @@ -845,6 +878,9 @@ class TypeChecker {
this.postCheckInit(ast);
// check unused virtualVariable & virtualMethod
this.postCheckTypes(ast);
if(!this.inner) {
this.checkExports(ast);
}
ast.models = {};
for (var [key, value] of this.models) {
ast.models[key] = value;
Expand Down Expand Up @@ -2547,7 +2583,6 @@ class TypeChecker {
} else {
model = this.models.get(type.name);
}

const find = checker.findProperty(model, propName, model.isException);
if (!find) {
return;
Expand Down Expand Up @@ -3368,7 +3403,7 @@ function analyze(source, filePath) {
while(!key.done) {
const ast = builtin.get(key.value);
if(ast.type === 'module') {
builtin.set(key.value, new TypeChecker(source, filePath).check(ast));
builtin.set(key.value, new TypeChecker(source, filePath, null, null, true).check(ast));
}
key = it.next();
}
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/multi_module/Darafile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"main": "./sdk.dara",
"libraries": {
"DARAUtil": "darabonba:Util:*"
},
"exports": {
"Resource": "./model/resource.dara"
}
}
4 changes: 4 additions & 0 deletions test/fixtures/multi_module/model/resource.dara
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
model Resource {
name: string,
age: integer,
}
1 change: 0 additions & 1 deletion test/lexer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ describe('lexer', function () {
{ tag: undefined, loc: loc(1, 14, 1, 14) }
]);

console.log('%j', lex('@prop({ key = "value" })', '__filename'));
expect(lex('@prop({ key = "value" })', '__filename')).to.be.eql([
{ tag: 43, lexeme: '@prop',
'loc': loc(1, 1, 1, 6)
Expand Down
21 changes: 21 additions & 0 deletions test/semantic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6996,6 +6996,27 @@ describe('semantic', function () {

it('use inner module should ok', function () {
let ast = readAndParse('fixtures/multi_module/sdk.dara');

const ResourceAst = ast.innerDep.get('Resource');
const [resourceModel] = ResourceAst.moduleBody.nodes;
expect(resourceModel.type).to.be('model');
expect(resourceModel.modelName).to.eql({
'tag': 2,
'loc':
{
'start': {
'line': 1,
'column': 7
},
'end':
{
'line': 1,
'column': 15
}
},
'lexeme':'Resource',
'index': 2
});

const userAst = ast.innerDep.get('User');
const [model] = userAst.moduleBody.nodes;
Expand Down

0 comments on commit 9ae3fb0

Please sign in to comment.