diff --git a/README.md b/README.md index 397cf5641fe498f6e60778f6bc8438d61568f10c..a73f404552bee35dc5854533c07b147ca8830afd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,11 @@ Run `ng generate component component-name` to generate a new component. You can ## Build -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. For example: + + ng build --prod --base-href "/doc/" + rsync -avz dist/ server:doc + ## Running unit tests diff --git a/TODO b/TODO index fba67dd966872212bb607ceb7db1fbf30a91961d..86d589680ba4ae0edb7ff05a9d6fb07531981a94 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,9 @@ ++ Add thrown type descriptions. -++ Add structured production representation. ++ Make current member filter more noticeable. ++ Add class overview as default page. ++ Make the title be a link to the default page. ++ Add modifier information to non-attribute members (public, static, etc.). +-- Add structured production representation. -- Add type hierarchy in type details. -- Add direct subtypes. -- Add declared-at info for types. diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 428066228a03745b694295b87451ef265046c175..e69849aa14f7831c19119abbdd5a8cb649cc6c9e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -73,14 +73,6 @@ export class AppComponent implements OnInit { this.packageService.getPackages().then(packages => this.packages = packages); } - declaredAt(member: Member): string { - if (member.doc) { - return `${member.doc.ragFile}:${member.doc.line}`; - } else { - return ""; - } - } - filteredPackage(pkg: Package): boolean { var filter = this.filter.toLowerCase(); for (var i = 0; i < pkg.groups.length; i++) { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f65502b76f463b8142d7f8f951321fd4ff8b6cd8..de1f12bced20396e560cbc9f5bfdec989ba13ace 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,6 +13,7 @@ import { StringFilterPipe } from './string-filter.pipe'; import { SourceViewComponent } from './source-view/source-view.component'; import { EditorDirective } from './editor.directive'; import { DeclaredAtComponent } from './declared-at/declared-at.component'; +import { AstDeclComponent } from './ast-decl/ast-decl.component'; @NgModule({ imports: [ @@ -40,6 +41,7 @@ import { DeclaredAtComponent } from './declared-at/declared-at.component'; SourceViewComponent, EditorDirective, DeclaredAtComponent, + AstDeclComponent, ], bootstrap: [ AppComponent ] }) diff --git a/src/app/ast-decl/ast-component.ts b/src/app/ast-decl/ast-component.ts new file mode 100644 index 0000000000000000000000000000000000000000..c3e62dc082829726301de29e49a366a426534cb3 --- /dev/null +++ b/src/app/ast-decl/ast-component.ts @@ -0,0 +1,23 @@ +import {TypeRef} from '../type-ref'; + +export class AstComponent { + name: string; + type: TypeRef; + kind: string; + + static fromJson(json: any): AstComponent { + var name: string = undefined; + if (json.n) { + name = json.n as string; + } + var kind = "regular"; + if (json.k) { + kind = json.k; + } + return { + name: json.n as string, + type: TypeRef.fromJson(json.e), + kind: kind, + }; + } +} diff --git a/src/app/ast-decl/ast-decl.component.spec.ts b/src/app/ast-decl/ast-decl.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..9a08ec2ec0f8f58b0d4c04fa99cac18106b0edb5 --- /dev/null +++ b/src/app/ast-decl/ast-decl.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AstDeclComponent } from './ast-decl.component'; + +describe('AstDeclComponent', () => { + let component: AstDeclComponent; + let fixture: ComponentFixture<AstDeclComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AstDeclComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AstDeclComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/ast-decl/ast-decl.component.ts b/src/app/ast-decl/ast-decl.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e7b3d7e15b5714be83f7f4b38c85fdff7432222 --- /dev/null +++ b/src/app/ast-decl/ast-decl.component.ts @@ -0,0 +1,51 @@ +import { Component, Input } from '@angular/core'; + +import {Doc} from '../doc'; +import {TypeRef} from '../type-ref'; +import {AstDecl} from './ast-decl'; + +@Component({ + selector: 'ast-decl', + styles: [` + .ast-decl { + font-weight: bold; + padding-left: 3em; + } + .ast-component { + padding-left: 4em; + } + `], + template: ` + <p *ngIf="_decl">JastAdd production: <br> + <div class="ast-decl">{{_decl.name}}: <type-ref [type]="_decl.extends"></type-ref><!-- + --><ng-container *ngIf="_decl.components"> ::= <!-- + --><ng-container *ngFor="let comp of _decl.components"><!-- + --><div class="ast-component"><!-- + --><ng-container *ngIf="comp.kind == 'regular'"><!-- + --><ng-container *ngIf="comp.name">{{comp.name}}:</ng-container><type-ref [type]="comp.type"></type-ref> <!-- + --></ng-container><!-- + --><ng-container *ngIf="comp.kind == 'list'"><!-- + --><ng-container *ngIf="comp.name">{{comp.name}}:</ng-container><type-ref [type]="comp.type"></type-ref>* <!-- + --></ng-container><!-- + --><ng-container *ngIf="comp.kind == 'opt'"><!-- + -->[<ng-container *ngIf="comp.name">{{comp.name}}:</ng-container><type-ref [type]="comp.type"></type-ref>] <!-- + --></ng-container><!-- + --><ng-container *ngIf="comp.kind == 'token'"><!-- + --><<ng-container *ngIf="comp.name">{{comp.name}}:</ng-container><type-ref [type]="comp.type"></type-ref>> <!-- + --></ng-container><!-- + --></div><!-- + --></ng-container><!-- + --></ng-container> + </div> + `, +}) +export class AstDeclComponent { + private _decl: AstDecl; + + constructor() { } + + @Input() + set decl(decl: AstDecl) { + this._decl = decl; + } +} diff --git a/src/app/ast-decl/ast-decl.ts b/src/app/ast-decl/ast-decl.ts new file mode 100644 index 0000000000000000000000000000000000000000..46c476d0be62ee94e25b0a84f0f31b6507960b34 --- /dev/null +++ b/src/app/ast-decl/ast-decl.ts @@ -0,0 +1,27 @@ +import {TypeRef} from '../type-ref'; +import {AstComponent} from './ast-component'; + +export class AstDecl { + name: string; + extends: TypeRef; + components?: AstComponent[]; + + static fromJson(json: any): AstDecl { + if (!json) { + return undefined; + } + var ext: TypeRef = undefined + if (json.e) { + ext = TypeRef.fromJson(json.e) + } + var components: AstComponent[] = undefined; + if (json.c) { + components = (json.c as any[]).map(c => AstComponent.fromJson(c)); + } + return { + name: json.n as string, + extends: ext, + components: components, + }; + } +} diff --git a/src/app/doc.ts b/src/app/doc.ts index d201353965df8dd94cd7693a2c7bebea9538d5b0..61e60baceede82afc01e16e80fee4072271e7063 100644 --- a/src/app/doc.ts +++ b/src/app/doc.ts @@ -1,26 +1,27 @@ +import {AstDecl} from './ast-decl/ast-decl'; + export class Doc { ast: string; + astdecl: AstDecl; ragFile: string; line: number; description: string; apilevel: string; params: string[] - paramDesc(name: string): string { - if (this.params) { - for (var i = 0; i < this.params.length; i++) { - var param = this.params[i]; - var index = param.indexOf(' '); - if (index >= 0 && param.substring(0, index) === name) { - return ' : ' + param.substring(index + 1); - } - } - } - return ''; - } - static fromJson(json: any): Doc { - var obj = Object.create(Doc.prototype); - return Object.assign(obj, json); + var astdecl: AstDecl = undefined; + if (json.astdecl) { + astdecl = AstDecl.fromJson(json.astdecl); + } + return { + ast: json.ast, + astdecl: astdecl, + ragFile: json.ragFile, + line: json.line, + description: json.description, + apilevel: json.apilevel, + params: json.params, + }; } } diff --git a/src/app/type-details.component.html b/src/app/type-details.component.html index 6a8b39ed72ec065eb2cd6230862cc594cb8f411e..dd431b9ccce3ce4cba63fbff20a78909f260b756 100644 --- a/src/app/type-details.component.html +++ b/src/app/type-details.component.html @@ -9,9 +9,9 @@ <div *ngIf="type.doc"> <p [innerHTML]="type.doc.description"> - <p *ngIf="type.doc.astdecl">JastAdd production: <b>{{type.doc.astdecl}}</b> + <p *ngIf="type.doc.astdecl"><ast-decl [decl]="type.doc.astdecl"></ast-decl> - <p *ngIf="type.doc && type.doc.ragFile"><declared-at [doc]="type.doc"></declared-at> + <p *ngIf="type.doc.ragFile"><declared-at [doc]="type.doc"></declared-at> </div> <div class="filter"> <input [(ngModel)]="filter" placeholder="Filter members..."> diff --git a/src/app/type-details.component.ts b/src/app/type-details.component.ts index 3d54cd6e1a221c37995b2ab3da865d1010fc234e..3154a0ff2c14e1550704c36c0b1d44743592bc1b 100644 --- a/src/app/type-details.component.ts +++ b/src/app/type-details.component.ts @@ -8,7 +8,7 @@ import { MemberFilterService } from './member-filter.service'; import { SelectionService } from './selection.service'; import { Member } from './member'; import { InheritedMembers } from './inherited-members'; -import {Doc} from './doc'; +import { Doc } from './doc'; import { Parameter } from './parameter'; import { ActivatedRoute, Params } from '@angular/router'; @@ -47,13 +47,15 @@ export class TypeDetailsComponent implements OnInit { }); } - declaredAt(doc: Doc): string { - return `${doc.ragFile}:${doc.line}`; - } - paramDesc(doc: Doc, name: string): string { - if (doc) { - return doc.paramDesc(name); + if (doc.params) { + for (var i = 0; i < doc.params.length; i++) { + var param = doc.params[i]; + var index = param.indexOf(' '); + if (index >= 0 && param.substring(0, index) === name) { + return ' : ' + param.substring(index + 1); + } + } } return ''; } diff --git a/src/app/type.ts b/src/app/type.ts index 8b7313903a081b44838220fda4e10e6e9cb0fbd5..c7c794bc2bd1531cc725fb6dc194c0aa8e3a4998 100644 --- a/src/app/type.ts +++ b/src/app/type.ts @@ -4,11 +4,11 @@ import {TypeRef} from './type-ref'; import {InheritedMembers} from './inherited-members'; export class Type { + id: string; kind: string; name: string; pkg: string; mods: string[]; - id: string; doc: Doc; groups: { [id: string] : Member[]; }; args: TypeRef[]; // Type arguments. @@ -20,6 +20,10 @@ export class Type { subtypes: TypeRef[]; static fromJson(json: any): Type { + var doc: Doc = undefined; + if (json.doc) { + doc = Doc.fromJson(json.doc); + } var groups = {}; if (json.groups) { for (var i = 0; i < json.groups.length; i++) { @@ -33,7 +37,7 @@ export class Type { if (json.superclass) { superclass = TypeRef.fromJson(json.superclass); } - var superinterfaces: TypeRef[] = undefined; + var superinterfaces: TypeRef[] = []; if (json.superinterfaces) { superinterfaces = (json.superinterfaces as TypeRef[]).map(TypeRef.fromJson); } @@ -60,16 +64,22 @@ export class Type { if (json.subtypes) { subtypes = (json.subtypes as any[]).map(arg => TypeRef.fromJson(arg)); } - return Object.assign({}, json, { - groups: groups, + return { id: TypeRef.typeId(json.name, json.id), + kind: json.kind, + name: json.name, + pkg: json.pkg, + mods: json.mods as string[], + doc: doc, + groups: groups, + args: args, superclass: superclass, superinterfaces: superinterfaces, inherited_methods: inherited_methods, inherited_attributes: inherited_attributes, inherited_fields: inherited_fields, subtypes: subtypes, - }); + }; } }