UNPKG

dockerfile-language-service

Version:

A language service for Dockerfiles to enable the creation of feature-rich Dockerfile editors.

205 lines (204 loc) 10.2 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "vscode-languageserver-types", "./docker", "dockerfile-ast"], factory); } })(function (require, exports) { /* -------------------------------------------------------------------------------------------- * Copyright (c) Remy Suen. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.DockerDefinition = void 0; var vscode_languageserver_types_1 = require("vscode-languageserver-types"); var docker_1 = require("./docker"); var dockerfile_ast_1 = require("dockerfile-ast"); var DockerDefinition = /** @class */ (function () { function DockerDefinition() { } DockerDefinition.prototype.computeBuildStageDefinition = function (dockerfile, position) { var source = undefined; for (var _i = 0, _a = dockerfile.getCOPYs(); _i < _a.length; _i++) { var instruction = _a[_i]; var flag = instruction.getFromFlag(); if (flag) { var range = flag.getValueRange(); if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) { source = flag.getValue(); break; } } } for (var _b = 0, _c = dockerfile.getFROMs(); _b < _c.length; _b++) { var instruction = _c[_b]; var range = instruction.getBuildStageRange(); if (range) { if (range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) { // cursor in FROM's build stage itself return range; } else if (source !== undefined && instruction.getBuildStage().toLowerCase() === source.toLowerCase()) { // FROM's build stage matches what's in COPY return range; } } range = instruction.getImageNameRange(); if (docker_1.Util.isInsideRange(position, range)) { var stageName = instruction.getImageName(); for (var _d = 0, _e = dockerfile.getFROMs(); _d < _e.length; _d++) { var from = _e[_d]; if (stageName === from.getBuildStage() && from.getRange().start.line < range.start.line) { return from.getBuildStageRange(); } } return null; } } return null; }; DockerDefinition.computeVariableDefinition = function (image, position) { var variableName = null; for (var _i = 0, _a = image.getARGs(); _i < _a.length; _i++) { var arg = _a[_i]; var property = arg.getProperty(); // might be an ARG with no arguments if (property) { // is the caret inside the definition itself if (docker_1.Util.isInsideRange(position, property.getNameRange())) { variableName = property.getName(); break; } } } if (variableName === null) { variableCheck: for (var _b = 0, _c = image.getENVs(); _b < _c.length; _b++) { var env = _c[_b]; var properties = env.getProperties(); for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) { var property = properties_1[_d]; // is the caret inside the definition itself if (docker_1.Util.isInsideRange(position, property.getNameRange())) { variableName = property.getName(); break variableCheck; } } } } if (variableName === null) { variableCheck: for (var _e = 0, _f = image.getInstructions(); _e < _f.length; _e++) { var instruction = _f[_e]; for (var _g = 0, _h = instruction.getVariables(); _g < _h.length; _g++) { var variable = _h[_g]; if (docker_1.Util.isInsideRange(position, variable.getNameRange())) { variableName = variable.getName(); break variableCheck; } } } } for (var _j = 0, _k = image.getInstructions(); _j < _k.length; _j++) { var instruction = _k[_j]; if (instruction instanceof dockerfile_ast_1.Arg) { var property = instruction.getProperty(); // might be an ARG with no arguments if (property && property.getName() === variableName) { return property; } } else if (instruction instanceof dockerfile_ast_1.Env) { var properties = instruction.getProperties(); for (var _l = 0, properties_2 = properties; _l < properties_2.length; _l++) { var property = properties_2[_l]; if (property.getName() === variableName) { return property; } } } } return null; }; DockerDefinition.findDefinition = function (dockerfile, position) { for (var _i = 0, _a = dockerfile.getFROMs(); _i < _a.length; _i++) { var from = _a[_i]; for (var _b = 0, _c = from.getVariables(); _b < _c.length; _b++) { var variable = _c[_b]; if (docker_1.Util.isInsideRange(position, variable.getNameRange())) { for (var _d = 0, _e = dockerfile.getInitialARGs(); _d < _e.length; _d++) { var arg = _e[_d]; var property = arg.getProperty(); if (property && property.getName() === variable.getName()) { return property; } } return null; } } } var image = dockerfile.getContainingImage(position); if (image === null) { return null; } return DockerDefinition.computeVariableDefinition(image, position); }; DockerDefinition.checkHeredocs = function (heredocs, position) { for (var _i = 0, heredocs_1 = heredocs; _i < heredocs_1.length; _i++) { var heredoc = heredocs_1[_i]; var nameRange = heredoc.getNameRange(); if (docker_1.Util.isInsideRange(position, nameRange)) { return docker_1.Util.isEmpty(nameRange) ? null : nameRange; } var delimiterRange = heredoc.getDelimiterRange(); if (delimiterRange !== null && docker_1.Util.isInsideRange(position, delimiterRange)) { return nameRange; } } return null; }; DockerDefinition.computeHeredocDefinition = function (dockerfile, position) { for (var _i = 0, _a = dockerfile.getInstructions(); _i < _a.length; _i++) { var instruction = _a[_i]; if (instruction instanceof dockerfile_ast_1.Copy) { var range = DockerDefinition.checkHeredocs(instruction.getHeredocs(), position); if (range !== null) { return range; } } else if (instruction instanceof dockerfile_ast_1.Run) { var range = DockerDefinition.checkHeredocs(instruction.getHeredocs(), position); if (range !== null) { return range; } } } return null; }; DockerDefinition.prototype.computeVariableDefinition = function (dockerfile, position) { var property = DockerDefinition.findDefinition(dockerfile, position); return property ? property.getNameRange() : null; }; DockerDefinition.prototype.computeDefinitionRange = function (content, position) { var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content); var range = this.computeBuildStageDefinition(dockerfile, position); if (range === null) { range = this.computeVariableDefinition(dockerfile, position); if (range === null) { return DockerDefinition.computeHeredocDefinition(dockerfile, position); } } return range; }; DockerDefinition.prototype.computeDefinition = function (textDocument, content, position) { var range = this.computeDefinitionRange(content, position); if (range !== null) { return vscode_languageserver_types_1.Location.create(textDocument.uri, range); } return null; }; return DockerDefinition; }()); exports.DockerDefinition = DockerDefinition; });