Add source information in the xml builder, print source file as part for veiw.toString

This commit is contained in:
Panayot Cankov
2016-03-14 18:04:53 +02:00
parent 6972e9213a
commit 522c9ee7ed
5 changed files with 55 additions and 8 deletions

View File

@ -0,0 +1,5 @@
<Page xmlns="http://schemas.nativescript.org/tns.xsd">
<GridLayout id="grid">
<Label id="label" text="Text" />
</GridLayout>
</Page>

View File

@ -24,6 +24,7 @@ import viewModule = require("ui/core/view");
import platform = require("platform"); import platform = require("platform");
import gesturesModule = require("ui/gestures"); import gesturesModule = require("ui/gestures");
import segmentedBar = require("ui/segmented-bar"); import segmentedBar = require("ui/segmented-bar");
import { Source } from "utils/debug";
export function test_load_IsDefined() { export function test_load_IsDefined() {
TKUnit.assert(types.isFunction(builder.load), "ui/builder should have load method!"); TKUnit.assert(types.isFunction(builder.load), "ui/builder should have load method!");
@ -974,3 +975,14 @@ export function test_TabViewHasCorrectParentChain() {
model.set("testPassed", false); model.set("testPassed", false);
helper.navigateToModuleAndRunTest(("." + moduleName + "/mymodulewithxml/TabViewParentChain"), model, testFunc); helper.navigateToModuleAndRunTest(("." + moduleName + "/mymodulewithxml/TabViewParentChain"), model, testFunc);
} }
export function test_hasSourceCodeLocations() {
var basePath = "xml-declaration/";
var page = <Page>builder.load(__dirname + "/examples/test-page.xml");
var grid = page.getViewById("grid");
var gridSource = Source.get(grid);
TKUnit.assertEqual(gridSource.toString(), "file:///app/" + basePath + "examples/test-page.xml:2:3");
var label = page.getViewById("label");
var labelSource = Source.get(label);
TKUnit.assertEqual(labelSource.toString(), "file:///app/" + basePath + "examples/test-page.xml:3:5");
}

View File

@ -44,10 +44,13 @@ function parseInternal(value: string, context: any, uri?: string): ComponentModu
var ui: xml2ui.ComponentParser; var ui: xml2ui.ComponentParser;
var errorFormat = (debug && uri) ? xml2ui.SourceErrorFormat(uri) : xml2ui.PositionErrorFormat; var errorFormat = (debug && uri) ? xml2ui.SourceErrorFormat(uri) : xml2ui.PositionErrorFormat;
var componentSourceTracker = (debug && uri) ? xml2ui.ComponentSourceTracker(uri) : () => {
// no-op
};
(start = new xml2ui.XmlStringParser(errorFormat)) (start = new xml2ui.XmlStringParser(errorFormat))
.pipe(new xml2ui.PlatformFilter()) .pipe(new xml2ui.PlatformFilter())
.pipe(new xml2ui.XmlStateParser(ui = new xml2ui.ComponentParser(context, errorFormat))); .pipe(new xml2ui.XmlStateParser(ui = new xml2ui.ComponentParser(context, errorFormat, componentSourceTracker)));
start.parse(value); start.parse(value);
@ -225,6 +228,19 @@ namespace xml2ui {
} }
} }
interface SourceTracker {
(component: any, p: xml.Position): void;
}
export function ComponentSourceTracker(uri): SourceTracker {
return (component: any, p: xml.Position) => {
if (!Source.get(component)) {
var source = p ? new Source(uri, p.line, p.column) : new Source(uri, -1, -1);
Source.set(component, source);
}
}
}
export class PlatformFilter extends XmlProducerBase implements XmlProducer, XmlConsumer { export class PlatformFilter extends XmlProducerBase implements XmlProducer, XmlConsumer {
private currentPlatformContext: string; private currentPlatformContext: string;
@ -293,6 +309,7 @@ namespace xml2ui {
elementName: string; elementName: string;
templateItems: Array<string>; templateItems: Array<string>;
errorFormat: ErrorFormatter; errorFormat: ErrorFormatter;
sourceTracker: SourceTracker;
} }
/** /**
@ -380,13 +397,14 @@ namespace xml2ui {
if (this._templateProperty.name in this._templateProperty.parent.component) { if (this._templateProperty.name in this._templateProperty.parent.component) {
var context = this._context; var context = this._context;
var errorFormat = this._templateProperty.errorFormat; var errorFormat = this._templateProperty.errorFormat;
var sourceTracker = this._templateProperty.sourceTracker;
var template: Template = () => { var template: Template = () => {
var start: xml2ui.XmlArgsReplay; var start: xml2ui.XmlArgsReplay;
var ui: xml2ui.ComponentParser; var ui: xml2ui.ComponentParser;
(start = new xml2ui.XmlArgsReplay(this._recordedXmlStream, errorFormat)) (start = new xml2ui.XmlArgsReplay(this._recordedXmlStream, errorFormat))
// No platform filter, it has been filtered allready // No platform filter, it has been filtered allready
.pipe(new XmlStateParser(ui = new ComponentParser(context, errorFormat))); .pipe(new XmlStateParser(ui = new ComponentParser(context, errorFormat, sourceTracker)));
start.replay(); start.replay();
@ -418,11 +436,13 @@ namespace xml2ui {
private parents = new Array<ComponentModule>(); private parents = new Array<ComponentModule>();
private complexProperties = new Array<ComponentParser.ComplexProperty>(); private complexProperties = new Array<ComponentParser.ComplexProperty>();
private error; private error: ErrorFormatter;
private sourceTracker: SourceTracker;
constructor(context: any, errorFormat: ErrorFormatter) { constructor(context: any, errorFormat: ErrorFormatter, sourceTracker: SourceTracker) {
this.context = context; this.context = context;
this.error = errorFormat; this.error = errorFormat;
this.sourceTracker = sourceTracker;
} }
public parse(args: xml.ParserEvent): XmlStateConsumer { public parse(args: xml.ParserEvent): XmlStateConsumer {
@ -450,7 +470,8 @@ namespace xml2ui {
name: name, name: name,
elementName: args.elementName, elementName: args.elementName,
templateItems: [], templateItems: [],
errorFormat: this.error errorFormat: this.error,
sourceTracker: this.sourceTracker
}); });
} }
@ -472,6 +493,7 @@ namespace xml2ui {
} }
if (componentModule) { if (componentModule) {
this.sourceTracker(componentModule.component, args.position);
if (parent) { if (parent) {
if (complexProperty) { if (complexProperty) {
// Add component to complex property of parent component. // Add component to complex property of parent component.

View File

@ -17,6 +17,7 @@ import * as visualStateConstants from "ui/styling/visual-state-constants";
import * as bindableModule from "ui/core/bindable"; import * as bindableModule from "ui/core/bindable";
import * as visualStateModule from "../styling/visual-state"; import * as visualStateModule from "../styling/visual-state";
import * as animModule from "ui/animation"; import * as animModule from "ui/animation";
import { Source } from "utils/debug";
var bindable: typeof bindableModule; var bindable: typeof bindableModule;
function ensureBindable() { function ensureBindable() {
@ -1151,11 +1152,18 @@ export class View extends ProxyObject implements definition.View {
} }
public toString(): string { public toString(): string {
var str = this.typeName;
if (this.id) { if (this.id) {
return this.typeName + `<${this.id}>`; str += `<${this.id}>`;
} else {
str += `(${this._domId})`;
}
var source = Source.get(this);
if (source) {
str += `@${source};`;
} }
return this.typeName + `(${this._domId})`; return str;
} }
public _setNativeViewFrame(nativeView: any, frame: any) { public _setNativeViewFrame(nativeView: any, frame: any) {

View File

@ -137,7 +137,7 @@ export class View extends viewCommon.View {
// flag not set, setMeasuredDimension() was not invoked, we raise // flag not set, setMeasuredDimension() was not invoked, we raise
// an exception to warn the developer // an exception to warn the developer
if ((this._privateFlags & PFLAG_MEASURED_DIMENSION_SET) !== PFLAG_MEASURED_DIMENSION_SET) { if ((this._privateFlags & PFLAG_MEASURED_DIMENSION_SET) !== PFLAG_MEASURED_DIMENSION_SET) {
throw new Error("onMeasure() did not set the measured dimension by calling setMeasuredDimension()"); throw new Error("onMeasure() did not set the measured dimension by calling setMeasuredDimension() " + this);
} }
} }
} }