Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
frenic committed Jul 10, 2018
1 parent 2cdbbcf commit b885649
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 80 deletions.
71 changes: 0 additions & 71 deletions src/keywords.ts

This file was deleted.

18 changes: 18 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,24 @@ function multiplierData(raw: string[]): MultiplierType | null {
}
}

export function precedenceCombinator(entities: EntityType[]) {
let combinator: ICombinator | null = null;

for (const entity of entities) {
if (isCombinator(entity)) {
if (!combinator) {
combinator = entity;
}
if (combinator !== entity) {
// This should never happen if grouping works as it should. So we just wnt to make sure.
throw new Error('Combinators must be grouped by precedence');
}
}
}

return combinator;
}

function groupByPrecedence(entities: EntityType[], precedence: number = Combinator.SingleBar): EntityType[] {
if (precedence < 0) {
// We've reached the lowest precedence possible
Expand Down
68 changes: 59 additions & 9 deletions src/typer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as cssTypes from 'mdn-data/css/types.json';
import { isProperty, isSyntax } from './data';
import { isProperty, isSyntax, getSyntax, getPropertySyntax } from './data';
import { warn } from './logger';
import {
import parse, {
Combinator,
Component,
EntityType,
Expand All @@ -10,8 +10,9 @@ import {
isMandatoryEntity,
isMandatoryMultiplied,
isOptionallyMultiplied,
isCurlyBracesMultiplier,
precedenceCombinator,
} from './parser';
import { combineKeywords } from './keywords';

export enum Type {
Alias,
Expand Down Expand Up @@ -50,6 +51,8 @@ export type TypeType<TDataType = IDataType> = IBasic | IStringLiteral | INumeric

export type ResolvedType = TypeType<DataType>;

const CURLY_BRACES_MULTIPLIER_MAXIMUM = 3;

let getBasicDataTypes = () => {
const types = Object.keys(cssTypes).reduce<{ [name: string]: IBasic }>((dataTypes, name) => {
switch (name) {
Expand Down Expand Up @@ -81,12 +84,10 @@ let getBasicDataTypes = () => {
};

export default function typing(entities: EntityType[]): TypeType[] {
if (combineKeywords(entities)) {
return [
{
type: Type.String,
},
];
const strictTypes = strictTyping(entities);

if (strictTypes !== null) {
return strictTypes;
}

let mandatoryCombinatorCount = 0;
Expand Down Expand Up @@ -179,6 +180,55 @@ export default function typing(entities: EntityType[]): TypeType[] {
return types;
}

export function strictTyping(entities: EntityType[]): TypeType[] | null {
const types: TypeType[] = [];
const combinator = precedenceCombinator(entities);

for (const entity of entities) {
if (isComponent(entity)) {
switch (entity.component) {
case Component.DataType: {
if (isSyntax(entity.value) || isProperty(entity.value)) {
const strictTypes = strictTyping(
parse(isSyntax(entity.value) ? getSyntax(entity.value) : getPropertySyntax(entity.value)),
);

if (strictTypes === null) {
return null;
}
}

// Missing or basic data type
return null;
}
case Component.Group: {
const strictTypes = strictTyping(entity.entities);

if (strictTypes === null) {
return null;
}

// TODO

break;
}
}

if (
entity.multiplier !== null &&
// We can work with a small amount. But too many isn't worth it.
!(isCurlyBracesMultiplier(entity.multiplier) && entity.multiplier.max < CURLY_BRACES_MULTIPLIER_MAXIMUM)
) {
return null;
}

continue;
}
}

return types;
}

function addLength<TDataType extends IDataType>(types: Array<TypeType<TDataType>>): Array<TypeType<TDataType>> {
if (types.every(type => type.type !== Type.Length)) {
return [
Expand Down

0 comments on commit b885649

Please sign in to comment.