Skip to content

Commit

Permalink
fix: add colon position to key node
Browse files Browse the repository at this point in the history
  • Loading branch information
pengx17 committed Dec 21, 2018
1 parent 84e82b5 commit ed907a9
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 16 deletions.
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"name": "vscode-jest-tests",
"request": "launch",
"args": ["--runInBand"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
]
}
1 change: 1 addition & 0 deletions src/languageservice/parser/jsonParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export class NumberASTNodeImpl extends ASTNodeImpl implements NumberASTNode {
export class StringASTNodeImpl extends ASTNodeImpl implements StringASTNode {
public type: 'string' = 'string';
public value: string;
public isKey: boolean;

constructor(parent: ASTNode, offset: number, length?: number) {
super(parent, offset, length);
Expand Down
3 changes: 3 additions & 0 deletions src/languageservice/parser/yamlParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
instance.endPosition - key.startPosition
);

result.colonOffset = key.colonPosition;

// Technically, this is an arbitrary node in YAML
// I doubt we would get a better string representation by parsing it
const keyNode = new StringASTNodeImpl(
Expand All @@ -69,6 +71,7 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode {
key.endPosition - key.startPosition
);
keyNode.value = key.value;
keyNode.isKey = true;

// TODO: calculate the correct NULL range.
const valueNode = instance.value
Expand Down
2 changes: 1 addition & 1 deletion src/languageservice/services/yamlCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class YAMLCompletion {

public configure(settings: LanguageSettings) {
if (settings) {
this.completionEnabled = settings.completion;
this.completionEnabled = settings.completion !== false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/languageservice/services/yamlHover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class YAMLHover {

public configure(languageSettings: LanguageSettings) {
if (languageSettings) {
this.shouldHover = !!languageSettings.hover;
this.shouldHover = languageSettings.hover !== false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/languageservice/services/yamlValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class YAMLValidation {

public configure(raw: LanguageSettings) {
if (raw) {
this.validationEnabled = raw.validate;
this.validationEnabled = raw.validate !== false;
}
}

Expand Down
117 changes: 112 additions & 5 deletions src/languageservice/yamlLanguageTypes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ASTNode } from './jsonLanguageTypes';
import { JSONDocument, IProblem } from './parser/jsonParser';
import { getPosition } from './utils/documentPositionCalculator';

export class SingleYAMLDocument extends JSONDocument {
public lines;
public lines: number[];
public errors: IProblem[];
public warnings: IProblem[];

Expand All @@ -23,6 +24,116 @@ export class SingleYAMLDocument extends JSONDocument {
return super.getNodeFromOffset(offset, true);
}

// getNodeFromOffsetEndInclusive(offset: number): ASTNode {
// if (!this.root) {
// return;
// }
// if (
// offset < this.root.offset ||
// offset > this.root.offset + this.root.length
// ) {
// // We somehow are completely outside the document
// // This is unexpected
// console.log('Attempting to resolve node outside of document');
// return null;
// }

// function* sliding2(nodes: ASTNode[]) {
// for (let i = 0; i < nodes.length; i ++) {
// yield [nodes[i], i === nodes.length ? null : nodes[i + 1]];
// }
// }

// const onLaterLine = (offset: number, node: ASTNode) => {
// const { line: actualLine } = getPosition(offset, this.lines);
// const { line: nodeEndLine } = getPosition(
// node.offset + node.length,
// this.lines
// );

// return actualLine > nodeEndLine;
// };

// let findNode = (nodes: ASTNode[]): ASTNode => {
// if (nodes.length === 0) {
// return null;
// }

// const gen = sliding2(nodes);

// for (let [first, second] of gen) {
// const end = second
// ? second.offset
// : first.parent.offset + first.parent.length;
// if (offset >= first.offset && offset < end) {
// const children = first.children;

// const foundChild = findNode(children);

// if (!foundChild && onLaterLine(offset, first)) {
// return this.getNodeByIndent(this.lines, offset, this.root);
// }

// return foundChild || first;
// }
// }

// return null;
// };

// return findNode(this.root.children) || this.root;
// }

// private getNodeByIndent = (
// lines: number[],
// offset: number,
// node: ASTNode
// ) => {
// const { line, column: indent } = getPosition(offset, this.lines);

// const children = node.children;

// function findNode(children: ASTNode[]) {
// if (children.length > 0) {

// }
// for (let idx = 0; idx < children.length; idx++) {
// const child = children[idx];

// const { line: childLine, column: childCol } = getPosition(
// child.offset,
// lines
// );

// if (childCol > indent) {
// return null;
// }

// const newChildren = child.children;
// const foundNode = findNode(newChildren);

// if (foundNode) {
// return foundNode;
// }

// // We have the right indentation, need to return based on line
// if (childLine == line) {
// return child;
// }
// if (childLine > line) {
// // Get previous
// idx - 1 >= 0 ? children[idx - 1] : child;
// }
// // Else continue loop to try next element
// }

// // Special case, we found the correct
// return children[children.length - 1];
// }

// return findNode(children) || node;
// };

public getNodeFromOffsetEndInclusive(offset: number): ASTNode {
const collector: ASTNode[] = [];
const findNode = (node: ASTNode): ASTNode => {
Expand Down Expand Up @@ -60,12 +171,8 @@ export class SingleYAMLDocument extends JSONDocument {

export class YAMLDocument {
public documents: SingleYAMLDocument[];
public errors;
public warnings;

constructor(documents: SingleYAMLDocument[]) {
this.documents = documents;
this.errors = [];
this.warnings = [];
}
}
11 changes: 5 additions & 6 deletions src/yaml-ast-parser/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,11 +492,7 @@ function storeMappingPair(
});

_result.mappings.push(mapping);
_result.endPosition = valueNode
? valueNode.endPosition
: keyNode.endPosition + 1; // FIXME.workaround should be position of ':' indeed
// }

_result.endPosition = mapping.endPosition;
return _result;
}

Expand Down Expand Up @@ -646,7 +642,8 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
_lineIndent,
_kind = state.kind,
_result = state.result,
ch;
ch,
_colonPosition = -1;
const state_result = ast.newScalar();
state_result.plainScalar = true;
state.result = state_result;
Expand Down Expand Up @@ -694,6 +691,7 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
is_WS_OR_EOL(following) ||
(withinFlowCollection && is_FLOW_INDICATOR(following))
) {
_colonPosition = state.position;
break;
}
} else if (0x23 /* # */ === ch) {
Expand Down Expand Up @@ -750,6 +748,7 @@ function readPlainScalar(state: State, nodeIndent, withinFlowCollection) {
state_result.startPosition,
state_result.endPosition
);
state_result.colonPosition = _colonPosition;
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions src/yaml-ast-parser/yamlAST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface YAMLNode extends YAMLDocument {
startPosition: number;
endPosition: number;
kind: Kind;
colonPosition?: number; // Nearest colon position.
anchorId?: string;
valueObject?: any;
parent: YAMLNode;
Expand Down Expand Up @@ -63,8 +64,7 @@ export interface YamlMap extends YAMLNode {
mappings: YAMLMapping[];
}
export function newMapping(key: YAMLScalar, value: YAMLNode): YAMLMapping {
const end = value ? value.endPosition : key.endPosition + 1; // FIXME.workaround, end should be defied by position of ':'
// console.log('key: ' + key.value + ' ' + key.startPosition + '..' + key.endPosition + ' ' + value + ' end: ' + end);
const end = value ? value.endPosition : key.colonPosition + 1;
const node = {
key,
value,
Expand Down
62 changes: 62 additions & 0 deletions test/yamlDocument.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { TextDocument } from 'vscode-languageserver';
import { parse as parseYAML } from '../src/languageservice/parser/yamlParser';

describe('SingleYAMLDocument tests', () => {
function setup(content: string) {
return TextDocument.create(
'file://~/Desktop/vscode-k8s/test.yaml',
'yaml',
0,
content
);
}

describe('getNodeFromOffsetEndInclusive', () => {
const content = `a :
b:
`;
function parseSetup(offset: number) {
const yamlDocs = parseYAML(content);

// Should be one doc only
expect(yamlDocs.documents.length).toBe(1);
return yamlDocs.documents[0].getNodeFromOffsetEndInclusive(offset);
}

it('0', () => {
const node = parseSetup(0);
expect(node.value).toBe('a');
expect(node.type).toBe('string');
});

it('1', () => {
const node = parseSetup(1);
expect(node.value).toBe('a');
expect(node.type).toBe('string');
});

it('2', () => {
const node = parseSetup(2);
expect(node.type).toBe('property');
});

it('6', () => {
const node = parseSetup(6);
expect(node.value).toBe('b');
expect(node.type).toBe('string');
});

it('7', () => {
const node = parseSetup(7);
expect(node.value).toBe('b');
expect(node.type).toBe('string');
});

it('8', () => {
const node = parseSetup(8);
expect(node.value).toBe('b');
expect(node.type).toBe('string');
});
});
});

0 comments on commit ed907a9

Please sign in to comment.