Skip to content

Commit 33a07c9

Browse files
committed
#12 start a prototype / WIP
1 parent f4fc83c commit 33a07c9

1 file changed

Lines changed: 122 additions & 8 deletions

File tree

src/repository.js

Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,11 @@ repository.prototype.scan = function(directory) {
199199
// ignore file (due to pattern)
200200
if (!matched) return done();
201201
// handle in-memory cache
202-
if (self.files.hasOwnProperty(filename)) {
202+
if (filename in self.files) {
203203
// check if need to parse again
204204
if (
205205
self.options.cacheByFileDate &&
206-
self.files[filename].mtime === stat.mtime.getTime()
206+
self.files[filename].mtime > stat.mtime.getTime()
207207
) {
208208
self.emit('cache', {
209209
name: filename
@@ -230,8 +230,10 @@ repository.prototype.scan = function(directory) {
230230
).then(function(file) {
231231
self.counter.loading--;
232232
self.counter.loaded++;
233-
self.counter.size += file.size;
234-
self.counter.symbols += file.nodes.length;
233+
if (file) {
234+
self.counter.size += file.size;
235+
self.counter.symbols += file.nodes.length;
236+
}
235237
self.emit('progress', self.counter);
236238
done();
237239
}, function(e) {
@@ -364,17 +366,15 @@ repository.prototype.parse = function(filename, encoding, stat) {
364366
self.files[filename] = new file(self, filename, ast);
365367
self.files[filename].refresh();
366368
self.files[filename].size = data.length;
367-
if (self.options.cacheByFileDate) {
368-
self.files[filename].mtime = data.length;
369-
}
370369
return done(self.files[filename]);
371370
} catch (e) {
372371
delete self.files[filename];
373372
self.emit('error', e);
374373
return reject(e);
375374
}
376375
}
377-
});
376+
}
377+
);
378378
}
379379
});
380380
return this.files[filename];
@@ -485,6 +485,120 @@ repository.prototype.getNamespace = function(name) {
485485
}
486486
};
487487

488+
/**
489+
* Synchronize with specified offset
490+
* @return {boolean} True is node is in sync
491+
*/
492+
repository.prototype.sync = function(filename, contents, offset) {
493+
if (!(filename in this.files)) {
494+
// not already in memory
495+
// @todo use the lazy cache
496+
var ast;
497+
try {
498+
var reader = new parser({
499+
ast: {
500+
withPositions: true
501+
},
502+
parser: {
503+
extractDoc: this.options.scanDocs,
504+
suppressErrors: true
505+
}
506+
});
507+
ast = reader.parseCode(
508+
contents, filename
509+
);
510+
} catch (e) {
511+
this.emit('error', e);
512+
return false;
513+
}
514+
this.files[filename] = new file(this, filename, ast);
515+
this.files[filename].refresh();
516+
this.files[filename].size = contents.length;
517+
// nothing to sync
518+
return true;
519+
}
520+
// @todo first implementation (not optimized for speed)
521+
// collect nodes
522+
var file = this.files[filename];
523+
var syncNode = null;
524+
var start = offset[0];
525+
var end = offset[1];
526+
for(var i = 0, size = file.nodes.length; i < size; i++) {
527+
var node = file.nodes[i];
528+
var position = node.position.offset;
529+
// x... [ ]
530+
// var isNodeAfter = position.start > start && position.end > end;
531+
// [ ] x...
532+
// var isNodeBefore = position.start > end;
533+
// [ x... ] or [ x.].. or x.[.. ] or x.[.].
534+
// var isNodeIntersect = !isNodeAfter && !isNodeBefore;
535+
// only [ x... ]
536+
var isNodeContainer = position.start <= start && position.end >= end;
537+
if (isNodeContainer) {
538+
// locate nodes to be synced :
539+
// [--[x..]--]
540+
// nodes that is not father of other nodes
541+
if (syncNode) {
542+
// lets naively think that the start offset should be greated (included from text position)
543+
if (syncNode.position.offset.start < position.start) {
544+
syncNode = node;
545+
}
546+
} else {
547+
syncNode = node;
548+
}
549+
}
550+
}
551+
if (!syncNode) {
552+
// refresh full file
553+
syncNode = file;
554+
}
555+
556+
var ast;
557+
try {
558+
var reader = new parser({
559+
ast: {
560+
withPositions: true
561+
},
562+
parser: {
563+
extractDoc: this.options.scanDocs,
564+
suppressErrors: true
565+
}
566+
});
567+
568+
if (syncNode.position.offset.start === 0) {
569+
// full refresh
570+
ast = reader.parseCode(contents, filename);
571+
// delete references
572+
file.remove();
573+
// create a new one
574+
this.files[filename] = new file(this, filename, ast);
575+
this.files[filename].refresh();
576+
this.files[filename].size = contents.length;
577+
} else {
578+
// inject parsing state
579+
reader.lexer.mode_eval = false;
580+
reader.lexer.all_tokens = false;
581+
reader.lexer.comment_tokens = this.options.scanDocs;
582+
reader.lexer.setInput(contents);
583+
reader.lexer.setState(syncNode.state);
584+
reader.lexer.begin('ST_IN_SCRIPTING');
585+
reader.parser._errors = [];
586+
reader.parser.filename = filename;
587+
reader.parser.currentNamespace = [''];
588+
// @notice innerList state (node not extracted to flag ignored)
589+
reader.parser.token = syncNode.state.token;
590+
// generic entry point :
591+
ast = reader.parser.read_top_statement();
592+
file.removeNode(syncNode);
593+
syncNode.parent.consumeChild(ast);
594+
}
595+
} catch (e) {
596+
this.emit('error', e);
597+
return false;
598+
}
599+
return true;
600+
};
601+
488602

489603
/**
490604
* Clean all the cache

0 commit comments

Comments
 (0)