UNPKG

3.54 kBJavaScriptView Raw
1// var utils = require('./utils');
2var goog = require('./goog');
3
4// TODO(vojta): can we handle provide "same thing provided multiple times" ?
5var DependencyResolver = function(logger) {
6 var log = logger.create('closure');
7
8 // the state
9 var fileMap = Object.create(null);
10 var provideMap = Object.create(null);
11
12 var updateProvideMap = function(filepath, oldProvides, newProvides) {
13 oldProvides.forEach(function(dep) {
14 if (provideMap[dep] === filepath) {
15 provideMap[dep] = null;
16 }
17 });
18
19 newProvides.forEach(function(dep) {
20 provideMap[dep] = filepath;
21 });
22 };
23
24 var resolveFile = function(filepath, files, alreadyResolvedMap) {
25 if (!fileMap[filepath]) {
26 // console.log('IGNORED', filepath);
27 files.push(filepath);
28 return;
29 }
30
31 // resolve all dependencies first
32 fileMap[filepath].requires.forEach(function(dep) {
33 if (!alreadyResolvedMap[dep]) {
34 if (provideMap[dep]) {
35 resolveFile(provideMap[dep], files, alreadyResolvedMap);
36 } else {
37 log.error('MISSING DEPENDENCY:', dep);
38 log.error('Did you forget to preprocess your source directory? Or did you leave off ' +
39 'the google closure library deps.js file?');
40 }
41 }
42 });
43
44 files.push(filepath);
45 fileMap[filepath].provides.forEach(function(dep) {
46 alreadyResolvedMap[dep] = true;
47 });
48 };
49
50 this.removeFile = function(filepath) {
51 if (!fileMap[filepath]) {
52 // console.log('Cannot remove unmapped file', filepath);
53 return;
54 }
55
56 fileMap[filepath].provides.forEach(function(dep) {
57 if (provideMap[dep] === filepath) {
58 provideMap[dep] = null;
59 }
60 });
61 fileMap[filepath] = null;
62 };
63
64 this.updateFile = function(filepath, content) {
65 var parsed = goog.parseProvideRequire(content);
66
67 if (!fileMap[filepath]) {
68 // console.log('New file', filepath, 'adding to the map.');
69 // console.log(parsed);
70 updateProvideMap(filepath, [], parsed.provides);
71 fileMap[filepath] = parsed;
72 return;
73 }
74
75 // var diffProvides = utils.diffSorted(fileMap[filepath].provides, parsed.provides);
76 // var diffRequires = utils.diffSorted(fileMap[filepath].requires, parsed.requires);
77
78 // if (diffProvides) {
79 // console.log('Provides change in', filepath);
80 // console.log('Added', diffProvides.added);
81 // console.log('Removed', diffProvides.removed);
82 // } else {
83 // console.log('No provides change in', filepath);
84 // }
85
86 // if (diffRequires) {
87 // console.log('Requires change in', filepath);
88 // console.log('Added', diffRequires.added);
89 // console.log('Removed', diffRequires.removed);
90 // } else {
91 // console.log('No requires change in', filepath);
92 // }
93
94 updateProvideMap(filepath, fileMap[filepath].provides, parsed.provides);
95 fileMap[filepath] = parsed;
96 };
97
98 this.resolveFiles = function(files) {
99 // console.log('RESOLVING', files);
100 // console.log(fileMap);
101
102 var resolvedFiles = [];
103 var alreadyResolvedMap = Object.create(null);
104
105 files.forEach(function(file) {
106 resolveFile(file, resolvedFiles, alreadyResolvedMap);
107 });
108
109 return resolvedFiles;
110 };
111
112 this.loadExternalDeps = function(filepath, content) {
113 var parsed = goog.parseDepsJs(filepath, content);
114
115 /* jshint camelcase: false, proto: true */
116 fileMap.__proto__ = parsed.fileMap;
117 provideMap.__proto__ = parsed.provideMap;
118 };
119};
120
121module.exports = DependencyResolver;