Skip to content

Commit 81c2689

Browse files
authored
Merge branch 'master' into esm-and-umd-libs
2 parents af0ecae + 6bd6126 commit 81c2689

10 files changed

+187
-60
lines changed

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88

99
#### 0.10.0
1010

11-
- Allows to declare a schema inside the yaml file through modeline `# yaml-language-server: $schema=<urlOfTheSchema>`
11+
- Allows to declare a schema inside the yaml file through modeline `# yaml-language-server: $schema=<urlOfTheSchema>` [#280](https://github.com/redhat-developer/yaml-language-server/pull/280)
12+
- Insert empty string instead of 'null' for string array completion [#277](https://github.com/redhat-developer/yaml-language-server/pull/277)
13+
- Handle workspace/workspaceFolders event for multi root workspaces [#281](https://github.com/redhat-developer/yaml-language-server/pull/281)
14+
- Provide default object as completion snippet [#291] https://github.com/redhat-developer/yaml-language-server/pull/291
15+
- Add validation of date and time formats [#292](https://github.com/redhat-developer/yaml-language-server/pull/292)
16+
- Fix document symbols computation if yaml has complex mappings [#293](https://github.com/redhat-developer/yaml-language-server/pull/293)
1217

1318
#### 0.9.0
1419

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "yaml-language-server",
33
"description": "YAML language server",
4-
"version": "0.9.0",
4+
"version": "0.10.1",
55
"author": "Gorkem Ercan (Red Hat)",
66
"license": "MIT",
77
"contributors": [

src/languageservice/parser/jsonParser07.ts

+29-32
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class ObjectASTNodeImpl extends ASTNodeImpl implements ObjectASTNode {
205205
}
206206
}
207207

208-
export function asSchema(schema: JSONSchemaRef) {
208+
export function asSchema(schema: JSONSchemaRef): JSONSchema {
209209
if (isBoolean(schema)) {
210210
return schema ? {} : { not: {} };
211211
}
@@ -238,13 +238,13 @@ export interface ISchemaCollector {
238238
class SchemaCollector implements ISchemaCollector {
239239
schemas: IApplicableSchema[] = [];
240240
constructor(private focusOffset = -1, private exclude: ASTNode = null) {}
241-
add(schema: IApplicableSchema) {
241+
add(schema: IApplicableSchema): void {
242242
this.schemas.push(schema);
243243
}
244-
merge(other: ISchemaCollector) {
244+
merge(other: ISchemaCollector): void {
245245
this.schemas.push(...other.schemas);
246246
}
247-
include(node: ASTNode) {
247+
include(node: ASTNode): boolean {
248248
return (this.focusOffset === -1 || contains(node, this.focusOffset)) && node !== this.exclude;
249249
}
250250
newSub(): ISchemaCollector {
@@ -256,16 +256,20 @@ class NoOpSchemaCollector implements ISchemaCollector {
256256
private constructor() {
257257
// ignore
258258
}
259-
get schemas() {
259+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
260+
get schemas(): any[] {
260261
return [];
261262
}
262-
add(schema: IApplicableSchema) {
263+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
264+
add(schema: IApplicableSchema): void {
263265
// ignore
264266
}
265-
merge(other: ISchemaCollector) {
267+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
268+
merge(other: ISchemaCollector): void {
266269
// ignore
267270
}
268-
include(node: ASTNode) {
271+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
272+
include(node: ASTNode): boolean {
269273
return true;
270274
}
271275
newSub(): ISchemaCollector {
@@ -383,7 +387,7 @@ export class ValidationResult {
383387
}
384388
}
385389

386-
export function newJSONDocument(root: ASTNode, diagnostics: Diagnostic[] = []) {
390+
export function newJSONDocument(root: ASTNode, diagnostics: Diagnostic[] = []): JSONDocument {
387391
return new JSONDocument(root, diagnostics, []);
388392
}
389393

@@ -468,7 +472,8 @@ function validate(
468472
validationResult: ValidationResult,
469473
matchingSchemas: ISchemaCollector,
470474
isKubernetes: boolean
471-
) {
475+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
476+
): any {
472477
if (!node || !matchingSchemas.include(node)) {
473478
return;
474479
}
@@ -481,10 +486,10 @@ function validate(
481486
_validateArrayNode(node, schema, validationResult, matchingSchemas);
482487
break;
483488
case 'string':
484-
_validateStringNode(node, schema, validationResult, matchingSchemas);
489+
_validateStringNode(node, schema, validationResult);
485490
break;
486491
case 'number':
487-
_validateNumberNode(node, schema, validationResult, matchingSchemas);
492+
_validateNumberNode(node, schema, validationResult);
488493
break;
489494
case 'property':
490495
return validate(node.valueNode, schema, validationResult, matchingSchemas, isKubernetes);
@@ -493,8 +498,8 @@ function validate(
493498

494499
matchingSchemas.add({ node: node, schema: schema });
495500

496-
function _validateNode() {
497-
function matchesType(type: string) {
501+
function _validateNode(): void {
502+
function matchesType(type: string): boolean {
498503
return node.type === type || (type === 'integer' && node.type === 'number' && node.isInteger);
499504
}
500505

@@ -540,7 +545,7 @@ function validate(
540545
}
541546
}
542547

543-
const testAlternatives = (alternatives: JSONSchemaRef[], maxOneMatch: boolean) => {
548+
const testAlternatives = (alternatives: JSONSchemaRef[], maxOneMatch: boolean): number => {
544549
const matches = [];
545550

546551
// remember the best match that is used for error messages
@@ -592,7 +597,7 @@ function validate(
592597
testAlternatives(schema.oneOf, true);
593598
}
594599

595-
const testBranch = (schema: JSONSchemaRef) => {
600+
const testBranch = (schema: JSONSchemaRef): void => {
596601
const subValidationResult = new ValidationResult(isKubernetes);
597602
const subMatchingSchemas = matchingSchemas.newSub();
598603

@@ -604,7 +609,7 @@ function validate(
604609
matchingSchemas.merge(subMatchingSchemas);
605610
};
606611

607-
const testCondition = (ifSchema: JSONSchemaRef, thenSchema?: JSONSchemaRef, elseSchema?: JSONSchemaRef) => {
612+
const testCondition = (ifSchema: JSONSchemaRef, thenSchema?: JSONSchemaRef, elseSchema?: JSONSchemaRef): void => {
608613
const subSchema = asSchema(ifSchema);
609614
const subValidationResult = new ValidationResult(isKubernetes);
610615
const subMatchingSchemas = matchingSchemas.newSub();
@@ -682,12 +687,7 @@ function validate(
682687
}
683688
}
684689

685-
function _validateNumberNode(
686-
node: NumberASTNode,
687-
schema: JSONSchema,
688-
validationResult: ValidationResult,
689-
matchingSchemas: ISchemaCollector
690-
): void {
690+
function _validateNumberNode(node: NumberASTNode, schema: JSONSchema, validationResult: ValidationResult): void {
691691
const val = node.value;
692692

693693
if (isNumber(schema.multipleOf)) {
@@ -748,12 +748,7 @@ function validate(
748748
}
749749
}
750750

751-
function _validateStringNode(
752-
node: StringASTNode,
753-
schema: JSONSchema,
754-
validationResult: ValidationResult,
755-
matchingSchemas: ISchemaCollector
756-
): void {
751+
function _validateStringNode(node: StringASTNode, schema: JSONSchema, validationResult: ValidationResult): void {
757752
if (isNumber(schema.minLength) && node.value.length < schema.minLength) {
758753
validationResult.problems.push({
759754
location: { offset: node.offset, length: node.length },
@@ -992,7 +987,7 @@ function validate(
992987
}
993988
}
994989

995-
const propertyProcessed = (prop: string) => {
990+
const propertyProcessed = (prop: string): void => {
996991
let index = unprocessedProperties.indexOf(prop);
997992
while (index >= 0) {
998993
unprocessedProperties.splice(index, 1);
@@ -1179,7 +1174,8 @@ function validate(
11791174
}
11801175

11811176
//Alternative comparison is specifically used by the kubernetes/openshift schema but may lead to better results then genericComparison depending on the schema
1182-
function alternativeComparison(subValidationResult, bestMatch, subSchema, subMatchingSchemas) {
1177+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1178+
function alternativeComparison(subValidationResult, bestMatch, subSchema, subMatchingSchemas): any {
11831179
const compareResult = subValidationResult.compareKubernetes(bestMatch.validationResult);
11841180
if (compareResult > 0) {
11851181
// our node is the best matching so far
@@ -1197,7 +1193,8 @@ function validate(
11971193
}
11981194

11991195
//genericComparison tries to find the best matching schema using a generic comparison
1200-
function genericComparison(maxOneMatch, subValidationResult, bestMatch, subSchema, subMatchingSchemas) {
1196+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1197+
function genericComparison(maxOneMatch, subValidationResult, bestMatch, subSchema, subMatchingSchemas): any {
12011198
if (!maxOneMatch && !subValidationResult.hasProblems() && !bestMatch.validationResult.hasProblems()) {
12021199
// no errors, both are equally good matches
12031200
bestMatch.matchingSchemas.merge(subMatchingSchemas);

src/languageservice/parser/recursivelyBuildAst.ts

-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ export default function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode
7878
const instance = <Yaml.YAMLScalar>node;
7979
const type = Yaml.determineScalarType(instance);
8080

81-
// The name is set either by the sequence or the mapping case.
82-
const name = null;
8381
const value = instance.value;
8482

8583
//This is a patch for redirecting values with these strings to be boolean nodes because its not supported in the parser.

src/languageservice/parser/yamlParser07.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { getLineStartPositions } from '../utils/documentPositionCalculator';
1717
import { ASTNode } from '../jsonASTTypes';
1818
import { ErrorCode } from 'vscode-json-languageservice';
1919

20-
const YAML_DIRECTIVE_PREFIX = '%';
2120
const YAML_COMMENT_PREFIX = '#';
2221
const YAML_DATA_INSTANCE_SEPARATOR = '---';
2322

@@ -43,7 +42,8 @@ export class SingleYAMLDocument extends JSONDocument {
4342
this.lineComments = [];
4443
}
4544

46-
public getSchemas(schema, doc, node) {
45+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
46+
public getSchemas(schema: any, doc: any, node: any): any[] {
4747
const matchingSchemas = [];
4848
doc.validate(schema, matchingSchemas, node.start);
4949
return matchingSchemas;
@@ -114,17 +114,17 @@ export function parse(text: string, customTags = []): YAMLDocument {
114114
return new YAMLDocument(yamlDocs);
115115
}
116116

117-
function parseLineComments(text: string, yamlDocs: SingleYAMLDocument[]) {
117+
function parseLineComments(text: string, yamlDocs: SingleYAMLDocument[]): void {
118118
const lines = text.split(/[\r\n]+/g);
119119
let yamlDocCount = 0;
120+
let firstSeparatorFound = false;
120121
lines.forEach((line) => {
121-
if (line.startsWith(YAML_DIRECTIVE_PREFIX) && yamlDocCount === 0) {
122-
yamlDocCount--;
123-
}
124-
if (line === YAML_DATA_INSTANCE_SEPARATOR) {
122+
if (line === YAML_DATA_INSTANCE_SEPARATOR && firstSeparatorFound) {
125123
yamlDocCount++;
124+
} else if (line === YAML_DATA_INSTANCE_SEPARATOR) {
125+
firstSeparatorFound = true;
126126
}
127-
if (line.startsWith(YAML_COMMENT_PREFIX)) {
127+
if (line.startsWith(YAML_COMMENT_PREFIX) && yamlDocCount < yamlDocs.length) {
128128
yamlDocs[yamlDocCount].lineComments.push(line);
129129
}
130130
});

src/languageservice/services/yamlSchemaService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export class YAMLSchemaService extends JSONSchemaService {
372372
if (schemaMatchs !== null && schemaMatchs.length >= 1) {
373373
if (schemaMatchs.length >= 2) {
374374
console.log(
375-
'Several $schema attributes has been found on the yaml-language-server modeline. The first one will be picked.'
375+
'Several $schema attributes have been found on the yaml-language-server modeline. The first one will be picked.'
376376
);
377377
}
378378
return schemaMatchs[0].substring('$schema='.length);

src/languageservice/yamlLanguageService.ts

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export interface Thenable<R> {
8181
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8282
then<TResult>(
8383
onfulfilled?: (value: R) => TResult | Thenable<TResult>,
84+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8485
onrejected?: (reason: any) => TResult | Thenable<TResult>
8586
): Thenable<TResult>;
8687
// eslint-disable-next-line @typescript-eslint/no-explicit-any

src/server.ts

+12-10
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
DocumentFormattingRequest,
2222
} from 'vscode-languageserver';
2323

24-
import { xhr, XHRResponse, configure as configureHttpRequests } from 'request-light';
24+
import { xhr, configure as configureHttpRequests } from 'request-light';
2525
import * as URL from 'url';
2626
import { removeDuplicatesObj } from './languageservice/utils/arrUtils';
2727
import {
@@ -155,7 +155,7 @@ const checkSchemaURI = (uri: string): string => {
155155
* AND the schema store setting is enabled. If the schema store setting
156156
* is not enabled we need to clear the schemas.
157157
*/
158-
function setSchemaStoreSettingsIfNotSet() {
158+
function setSchemaStoreSettingsIfNotSet(): void {
159159
const schemaStoreIsSet = schemaStoreSettings.length !== 0;
160160

161161
if (schemaStoreEnabled && !schemaStoreIsSet) {
@@ -164,7 +164,7 @@ function setSchemaStoreSettingsIfNotSet() {
164164
schemaStoreSettings = schemaStore.schemas;
165165
updateConfiguration();
166166
})
167-
.catch((error: XHRResponse) => {
167+
.catch(() => {
168168
// ignore
169169
});
170170
} else if (!schemaStoreEnabled) {
@@ -176,7 +176,8 @@ function setSchemaStoreSettingsIfNotSet() {
176176
/**
177177
* When the schema store is enabled, download and store YAML schema associations
178178
*/
179-
function getSchemaStoreMatchingSchemas() {
179+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
180+
function getSchemaStoreMatchingSchemas(): Promise<{ schemas: any[] }> {
180181
return xhr({ url: JSON_SCHEMASTORE_URL }).then((response) => {
181182
const languageSettings = {
182183
schemas: [],
@@ -208,9 +209,9 @@ function getSchemaStoreMatchingSchemas() {
208209

209210
/**
210211
* Called when server settings or schema associations are changed
211-
* Re-creates schema associations and revalidates any open YAML files
212+
* Re-creates schema associations and re-validates any open YAML files
212213
*/
213-
function updateConfiguration() {
214+
function updateConfiguration(): void {
214215
let languageSettings: LanguageSettings = {
215216
validate: yamlShouldValidate,
216217
hover: yamlShouldHover,
@@ -267,7 +268,8 @@ function updateConfiguration() {
267268
* @param schema schema id
268269
* @param languageSettings current server settings
269270
*/
270-
function configureSchemas(uri: string, fileMatch: string[], schema: any, languageSettings: LanguageSettings) {
271+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
272+
function configureSchemas(uri: string, fileMatch: string[], schema: any, languageSettings: LanguageSettings): LanguageSettings {
271273
uri = checkSchemaURI(uri);
272274

273275
if (schema === null) {
@@ -287,7 +289,7 @@ function configureSchemas(uri: string, fileMatch: string[], schema: any, languag
287289
return languageSettings;
288290
}
289291

290-
function isKubernetes(textDocument: TextDocument) {
292+
function isKubernetes(textDocument: TextDocument): boolean {
291293
for (const path in specificValidatorPaths) {
292294
const globPath = specificValidatorPaths[path];
293295
const fpa = new FilePatternAssociation(globPath);
@@ -339,7 +341,7 @@ function validateTextDocument(textDocument: TextDocument): void {
339341
diagnostics: removeDuplicatesObj(diagnostics),
340342
});
341343
},
342-
function (error) {
344+
function () {
343345
// ignore
344346
}
345347
);
@@ -547,7 +549,7 @@ documents.onDidClose((event) => {
547549

548550
/**
549551
* Called when a monitored file is changed in an editor
550-
* Revalidates the entire document
552+
* Re-validates the entire document
551553
*/
552554
connection.onDidChangeWatchedFiles((change) => {
553555
let hasChanges = false;

test/schemaValidation.test.ts

+38
Original file line numberDiff line numberDiff line change
@@ -777,4 +777,42 @@ suite('Validation Tests', () => {
777777
.then(done, done);
778778
});
779779
});
780+
781+
describe('Multi Document schema validation tests', () => {
782+
it('Document does not error when --- is present with schema', (done) => {
783+
languageService.addSchema(SCHEMA_ID, {
784+
type: 'object',
785+
properties: {
786+
cwd: {
787+
type: 'string',
788+
},
789+
},
790+
});
791+
const content = '---\n# this is a test\ncwd: this';
792+
const validator = parseSetup(content);
793+
validator
794+
.then(function (result) {
795+
assert.equal(result.length, 0);
796+
})
797+
.then(done, done);
798+
});
799+
800+
it('Multi Document does not error when --- is present with schema', (done) => {
801+
languageService.addSchema(SCHEMA_ID, {
802+
type: 'object',
803+
properties: {
804+
cwd: {
805+
type: 'string',
806+
},
807+
},
808+
});
809+
const content = '---\n# this is a test\ncwd: this...\n---\n# second comment\ncwd: hello\n...';
810+
const validator = parseSetup(content);
811+
validator
812+
.then(function (result) {
813+
assert.equal(result.length, 0);
814+
})
815+
.then(done, done);
816+
});
817+
});
780818
});

0 commit comments

Comments
 (0)