Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Hanson committed Sep 28, 2016
1 parent 0e7fa4f commit a98bf56
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 79 deletions.
8 changes: 4 additions & 4 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace ts {

let symbolCount = 0;
let Symbol: { new (flags: SymbolFlags, name: string): Symbol };
let classifiableNames: Map<string>;
let classifiableNames: Set;

const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
Expand All @@ -140,7 +140,7 @@ namespace ts {
options = opts;
languageVersion = getEmitScriptTarget(options);
inStrictMode = !!file.externalModuleIndicator;
classifiableNames = createMap<string>();
classifiableNames = createSet();
symbolCount = 0;
skipTransformFlagAggregation = isDeclarationFile(file);

Expand Down Expand Up @@ -335,7 +335,7 @@ namespace ts {
symbol = _getOrUpdate(symbolTable, name, name => createSymbol(SymbolFlags.None, name));

if (name && (includes & SymbolFlags.Classifiable)) {
_s(classifiableNames, name, name);
_add(classifiableNames, name);
}

if (symbol.flags & excludes) {
Expand Down Expand Up @@ -2089,7 +2089,7 @@ namespace ts {
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
// Add name of class expression into the map for semantic classifier
if (node.name) {
_s(classifiableNames, node.name.text, node.name.text);
_add(classifiableNames, node.name.text);
}
}

Expand Down
26 changes: 13 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7620,7 +7620,7 @@ namespace ts {
let targetStack: Type[];
let depth = 0;
let inferiority = 0;
const visited = createMap<boolean>();
const visited = createSet();
inferFromTypes(originalSource, originalTarget);

function isInProcess(source: Type, target: Type) {
Expand Down Expand Up @@ -7756,10 +7756,10 @@ namespace ts {
return;
}
const key = source.id + "," + target.id;
if (_g(visited, key)) {
if (_setHas(visited, key)) {
return;
}
_s(visited, key, true);
_add(visited, key);
if (depth === 0) {
sourceStack = [];
targetStack = [];
Expand Down Expand Up @@ -10377,7 +10377,7 @@ namespace ts {
}
}

function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
function checkJsxAttribute(node: JsxAttribute, elementAttributesType: Type, nameTable: Set) {
let correspondingPropType: Type = undefined;

// Look up the corresponding property for this attribute
Expand Down Expand Up @@ -10416,24 +10416,24 @@ namespace ts {
checkTypeAssignableTo(exprType, correspondingPropType, node);
}

_s(nameTable, node.name.text, true);
_add(nameTable, node.name.text);
return exprType;
}

function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Map<boolean>) {
function checkJsxSpreadAttribute(node: JsxSpreadAttribute, elementAttributesType: Type, nameTable: Set) {
const type = checkExpression(node.expression);
const props = getPropertiesOfType(type);
for (const prop of props) {
// Is there a corresponding property in the element attributes type? Skip checking of properties
// that have already been assigned to, as these are not actually pushed into the resulting type
if (!_g(nameTable, prop.name)) {
if (!_setHas(nameTable, prop.name)) {
const targetPropSym = getPropertyOfType(elementAttributesType, prop.name);
if (targetPropSym) {
const msg = chainDiagnosticMessages(undefined, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property, prop.name);
checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(targetPropSym), node, undefined, msg);
}

_s(nameTable, prop.name, true);
_add(nameTable, prop.name);
}
}
return type;
Expand Down Expand Up @@ -10749,7 +10749,7 @@ namespace ts {

const targetAttributesType = getJsxElementAttributesType(node);

const nameTable = createMap<boolean>();
const nameTable = createSet();
// Process this array in right-to-left order so we know which
// attributes (mostly from spreads) are being overwritten and
// thus should have their types ignored
Expand All @@ -10773,7 +10773,7 @@ namespace ts {
const targetProperties = getPropertiesOfType(targetAttributesType);
for (let i = 0; i < targetProperties.length; i++) {
if (!(targetProperties[i].flags & SymbolFlags.Optional) &&
!_g(nameTable, targetProperties[i].name)) {
!_setHas(nameTable, targetProperties[i].name)) {

error(node, Diagnostics.Property_0_is_missing_in_type_1, targetProperties[i].name, typeToString(targetAttributesType));
}
Expand Down Expand Up @@ -14229,7 +14229,7 @@ namespace ts {
}

function checkObjectTypeForDuplicateDeclarations(node: TypeLiteralNode | InterfaceDeclaration) {
const names = createMap<boolean>();
const names = createSet();
for (const member of node.members) {
if (member.kind == SyntaxKind.PropertySignature) {
let memberName: string;
Expand All @@ -14243,12 +14243,12 @@ namespace ts {
continue;
}

if (_g(names, memberName)) {
if (_setHas(names, memberName)) {
error(member.symbol.valueDeclaration.name, Diagnostics.Duplicate_identifier_0, memberName);
error(member.name, Diagnostics.Duplicate_identifier_0, memberName);
}
else {
_s(names, memberName, true);
_add(names, memberName);
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,9 +975,6 @@ namespace ts {
function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypingOptions, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {

//kill
checkNotNativeMap(jsonOptions);

if (!jsonOptions) {
return;
}
Expand Down
59 changes: 32 additions & 27 deletions src/compiler/dataStructures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace ts {
}

declare const Map: { new<T>(): NativeMap<T> } | undefined;
const realMaps = typeof Map !== "undefined"; //false;
const realMaps = typeof Map !== "undefined";

const createObject = Object.create;
const hasOwnProperty = Object.prototype.hasOwnProperty;
Expand Down Expand Up @@ -92,8 +92,6 @@ namespace ts {
return map;
}

//PRIMITIVE OPERATIONS: Need a different strategy for real map vs {}

export const _g: <T>(map: Map<T>, key: string) => T = realMaps
? <T>(map: NativeMap<T>, key: string) => map.get(key)
: <T>(map: MapLike<T>, key: string) => map[key];
Expand Down Expand Up @@ -139,7 +137,6 @@ namespace ts {

export const _find: <T, U>(map: Map<T>, f: (key: string, value: T) => U | undefined) => U | undefined = realMaps
? <T, U>(map: NativeMap<T>, f: (key: string, value: T) => U | undefined) => {
//use forEach?
const iter = map.entries();
while (true) {
const { value: pair, done } = iter.next();
Expand Down Expand Up @@ -321,11 +318,6 @@ namespace ts {
}
return undefined;
};

//kill
export function checkNotNativeMap(value: MapLike<any>) {
Debug.assert(!(value instanceof Map));
}
}


Expand Down Expand Up @@ -366,12 +358,18 @@ namespace ts {
* @param source A map from which properties should be copied.
* @param target A map to which properties should be copied.
*/
//rename : "entries", not "properties"
export function copyMapPropertiesFromTo<T>(source: Map<T>, target: Map<T>): void {
_each(source, (key, value) => {
_s(target, key, value);
});
}

//move
export function copySetValuesFromTo<T>(source: Set, target: Set): void {
_eachInSet(source, value => _add(target, value));
}

//kill?
/**
* Reduce the properties of a map.
Expand Down Expand Up @@ -497,16 +495,39 @@ namespace ts {
declare const Set: { new(): NativeSet } | undefined;
const realSets = typeof Set !== "undefined";

/*interface StringSetModule {
createSet(): Set
add(set: Set, value: string): string;
}
const StringSet: StringSetModule = realSets ?
{
createSet: () => new Set(),
add(set: NativeSet, value: string) {
set.add(value);
return value;
}
}
:
{
createSet: () => createDictionaryModeObject(),
add(set: SetLike, value: string) {
set[value] = true;
return value;
}
}*/

export const createSet: () => Set = realSets
? () => new Set()
: () => createDictionaryModeObject();

export const _add: (set: Set, value: string) => void = realSets
export const _add: (set: Set, value: string) => string = realSets
? (set: NativeSet, value: string) => {
set.add(value);
return value;
}
: (set: SetLike, value: string) => {
set[value] = true;
return value;
}

export const _setHas: (set: Set, value: string) => boolean = realSets
Expand Down Expand Up @@ -537,15 +558,9 @@ namespace ts {
for (const value in set)
f(value);
}

//todo: more iteration helpers
}





//MAPLIKE CRAP
//MAPLIKE
/* @internal */
namespace ts {
const hasOwnProperty = Object.prototype.hasOwnProperty; //neater
Expand All @@ -570,7 +585,6 @@ namespace ts {
* @param key A property key.
*/
export function hasProperty<T>(map: MapLike<T>, key: string): boolean {
checkNotNativeMap(map);
return hasOwnProperty.call(map, key);
}

Expand All @@ -584,7 +598,6 @@ namespace ts {
* @param key A property key.
*/
export function getProperty<T>(map: MapLike<T>, key: string): T | undefined {
checkNotNativeMap(map);
return hasOwnProperty.call(map, key) ? map[key] : undefined;
}

Expand All @@ -597,7 +610,6 @@ namespace ts {
* @param map A map-like.
*/
export function getOwnKeys<T>(map: MapLike<T>): string[] {
checkNotNativeMap(map);
const keys: string[] = [];
for (const key in map) if (hasOwnProperty.call(map, key)) {
keys.push(key);
Expand All @@ -609,9 +621,7 @@ namespace ts {
export function assign<T1 extends MapLike<{}>, T2>(t: T1, arg1: T2): T1 & T2;
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]): any;
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]) {
checkNotNativeMap(t);
for (const arg of args) {
checkNotNativeMap(arg);
for (const p of getOwnKeys(arg)) {
t[p] = arg[p];
}
Expand All @@ -630,7 +640,6 @@ namespace ts {
* @param initial The initial value for the reduction.
*/
export function reduceOwnProperties<T, U>(map: MapLike<T>, callback: (aggregate: U, value: T, key: string) => U, initial: U): U {
checkNotNativeMap(map);
let result = initial;
for (const key in map) if (hasOwnProperty.call(map, key)) {
result = callback(result, map[key], String(key));
Expand All @@ -645,8 +654,6 @@ namespace ts {
* @param right A map-like whose properties should be compared.
*/
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>, equalityComparer?: (left: T, right: T) => boolean) {
checkNotNativeMap(left);
checkNotNativeMap(right);
if (left === right) return true;
if (!left || !right) return false;
for (const key in left) if (hasOwnProperty.call(left, key)) {
Expand All @@ -660,8 +667,6 @@ namespace ts {
}

export function extend<T1, T2>(first: T1 , second: T2): T1 & T2 {
checkNotNativeMap(first);
checkNotNativeMap(second);
const result: T1 & T2 = <any>{};
for (const id in second) if (hasOwnProperty.call(second, id)) {
(result as any)[id] = (second as any)[id];
Expand Down
10 changes: 5 additions & 5 deletions src/compiler/declarationEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace ts {
// and we could be collecting these paths from multiple files into single one with --out option
let referencesOutput = "";

let usedTypeDirectiveReferences: Map<string>;
let usedTypeDirectiveReferences: Set;

// Emit references corresponding to each file
const emittedReferencedFiles: SourceFile[] = [];
Expand Down Expand Up @@ -156,7 +156,7 @@ namespace ts {
});

if (usedTypeDirectiveReferences) {
_eachKey(usedTypeDirectiveReferences, directive => {
_eachInSet(usedTypeDirectiveReferences, directive => {
referencesOutput += `/// <reference types="${directive}" />${newLine}`;
});
}
Expand Down Expand Up @@ -267,11 +267,11 @@ namespace ts {
}

if (!usedTypeDirectiveReferences) {
usedTypeDirectiveReferences = createMap<string>();
usedTypeDirectiveReferences = createSet();
}
for (const directive of typeReferenceDirectives) {
if (!_has(usedTypeDirectiveReferences, directive)) {
_s(usedTypeDirectiveReferences, directive, directive);
if (!_setHas(usedTypeDirectiveReferences, directive)) {
_add(usedTypeDirectiveReferences, directive);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ const _super = (function (geti, seti) {

let nodeIdToGeneratedName: string[];
let autoGeneratedIdToGeneratedName: string[];
let generatedNameSet: Map<string>;
let generatedNameSet: Set;
let tempFlags: TempFlags;
let currentSourceFile: SourceFile;
let currentText: string;
Expand Down Expand Up @@ -296,7 +296,7 @@ const _super = (function (geti, seti) {
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
nodeIdToGeneratedName = [];
autoGeneratedIdToGeneratedName = [];
generatedNameSet = createMap<string>();
generatedNameSet = createSet();
isOwnFileEmit = !isBundledEmit;

// Emit helpers from all the files
Expand Down Expand Up @@ -2704,7 +2704,7 @@ const _super = (function (geti, seti) {
function isUniqueName(name: string): boolean {
return !resolver.hasGlobalName(name) &&
!_has(currentFileIdentifiers, name) &&
!_has(generatedNameSet, name);
!_setHas(generatedNameSet, name);
}

function isUniqueLocalName(name: string, container: Node): boolean {
Expand Down Expand Up @@ -2760,7 +2760,7 @@ const _super = (function (geti, seti) {
while (true) {
const generatedName = baseName + i;
if (isUniqueName(generatedName)) {
return _s(generatedNameSet, generatedName, generatedName);
return _add(generatedNameSet, generatedName);
}
i++;
}
Expand Down
Loading

0 comments on commit a98bf56

Please sign in to comment.