Introduce "special" query kind
parent
c843463c0e
commit
9941cbf380
|
@ -86,8 +86,10 @@ export default class Collector {
|
|||
// TODO: warning.
|
||||
invariant(result.kind !== 'unknown');
|
||||
|
||||
// Resulting scope is always the best choice for waiting.
|
||||
scope = result.scope;
|
||||
if (result.kind !== 'special') {
|
||||
// Resulting scope is always the best choice for waiting.
|
||||
scope = result.scope;
|
||||
}
|
||||
|
||||
// It's only valid the sequence: E*[CT]?F,
|
||||
// where E - external, C - declaration, T - template, F - definition.
|
||||
|
@ -141,6 +143,13 @@ export default class Collector {
|
|||
// Fallthrough.
|
||||
case 'definition':
|
||||
return result.type;
|
||||
|
||||
case 'special':
|
||||
const type = result.call(params);
|
||||
|
||||
invariant(type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
invariant(false);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
export default [
|
||||
{
|
||||
id: ['Buffer'],
|
||||
kind: 'record',
|
||||
fields: [],
|
||||
export default {
|
||||
Buffer() {
|
||||
return {
|
||||
kind: 'reference',
|
||||
to: ["Buffer"],
|
||||
};
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
10
src/query.js
10
src/query.js
|
@ -8,7 +8,8 @@ export type Query =
|
|||
| Declaration
|
||||
| Template
|
||||
| Definition
|
||||
| External;
|
||||
| External
|
||||
| Special;
|
||||
|
||||
export type Unknown = {
|
||||
kind: 'unknown',
|
||||
|
@ -42,6 +43,13 @@ export type External = {
|
|||
scope: Scope,
|
||||
};
|
||||
|
||||
export type Special = {
|
||||
kind: 'special',
|
||||
call: SpecialFn,
|
||||
};
|
||||
|
||||
export type SpecialFn = (?Type)[] => ?Type;
|
||||
|
||||
export type TemplateParam = {
|
||||
name: string,
|
||||
value: ?Type,
|
||||
|
|
22
src/scope.js
22
src/scope.js
|
@ -4,7 +4,7 @@ import type {Node} from '@babel/types';
|
|||
import {invariant, last} from './utils';
|
||||
import type Module from './module';
|
||||
import type {Type, TypeId} from './types';
|
||||
import type {Query, Template, TemplateParam, ExternalInfo} from './query';
|
||||
import type {Query, Template, TemplateParam, ExternalInfo, SpecialFn} from './query';
|
||||
|
||||
export default class Scope {
|
||||
+id: TypeId;
|
||||
|
@ -12,16 +12,13 @@ export default class Scope {
|
|||
+module: ?Module;
|
||||
_entries: Map<string, Query>;
|
||||
|
||||
static global(types: Type[]) {
|
||||
static global(specials: {[string]: SpecialFn}) {
|
||||
const global = new Scope(null, null);
|
||||
|
||||
for (const type of types) {
|
||||
invariant(type.id);
|
||||
for (const name in specials) {
|
||||
const fn = specials[name];
|
||||
|
||||
const name = last(type.id);
|
||||
invariant(name != null);
|
||||
|
||||
global.addDefinition(name, type, false);
|
||||
global.addSpecial(name, fn);
|
||||
}
|
||||
|
||||
return global;
|
||||
|
@ -38,6 +35,15 @@ export default class Scope {
|
|||
return new Scope(this, module || this.module);
|
||||
}
|
||||
|
||||
addSpecial(name: string, fn: SpecialFn) {
|
||||
invariant(!this._entries.has(name));
|
||||
|
||||
this._entries.set(name, {
|
||||
kind: 'special',
|
||||
call: fn,
|
||||
});
|
||||
}
|
||||
|
||||
addDeclaration(name: string, node: Node, params: TemplateParam[]) {
|
||||
invariant(!this._entries.has(name));
|
||||
|
||||
|
|
Loading…
Reference in New Issue