Esempio n. 1
0
 DockerDefinition.prototype.computeDefinition = function (textDocument, content, position) {
     var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
     var range = this.computeBuildStageDefinition(dockerfile, position);
     if (range !== null) {
         return vscode_languageserver_types_1.Location.create(textDocument.uri, range);
     }
     range = this.computeVariableDefinition(dockerfile, position);
     if (range !== null) {
         return vscode_languageserver_types_1.Location.create(textDocument.uri, range);
     }
     return null;
 };
Esempio n. 2
0
 parseSymbolInformation(document, textDocumentURI) {
     let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
     let directive = dockerfile.getDirective();
     let symbols = [];
     if (directive !== null) {
         symbols.push(this.createSymbolInformation(directive.getName(), textDocumentURI, directive.getNameRange(), vscode_languageserver_1.SymbolKind.Property));
     }
     for (let instruction of dockerfile.getInstructions()) {
         symbols.push(this.createSymbolInformation(instruction.getInstruction(), textDocumentURI, instruction.getInstructionRange(), vscode_languageserver_1.SymbolKind.Function));
     }
     return symbols;
 }
Esempio n. 3
0
 /**
  * Formats the specified lines of the given document based on the
  * provided formatting options.
  *
  * @param document the text document to format
  * @param lines the lines to format
  * @param options the formatting options to use to perform the format
  * @return the text edits to apply to format the lines of the document
  */
 format(document, lines, options) {
     let content = document.getText();
     let dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
     const indentedLines = [];
     for (let i = 0; i < document.lineCount; i++) {
         indentedLines[i] = false;
     }
     for (let instruction of dockerfile.getInstructions()) {
         let range = instruction.getRange();
         indentedLines[range.start.line] = false;
         for (let i = range.start.line + 1; i <= range.end.line; i++) {
             indentedLines[i] = true;
         }
     }
     return this.formatLines(document, content, lines, indentedLines, options);
 }
Esempio n. 4
0
 DockerFormatter.prototype.format = function (content, lines, options) {
     var document = vscode_languageserver_types_1.TextDocument.create("", "", 0, content);
     var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
     var indentedLines = [];
     for (var i = 0; i < document.lineCount; i++) {
         indentedLines[i] = false;
     }
     for (var _i = 0, _a = dockerfile.getInstructions(); _i < _a.length; _i++) {
         var instruction = _a[_i];
         var range = instruction.getRange();
         indentedLines[range.start.line] = false;
         for (var i = range.start.line + 1; i <= range.end.line; i++) {
             indentedLines[i] = true;
         }
     }
     return this.formatLines(document, content, lines, indentedLines, options);
 };
Esempio n. 5
0
 DockerFormatter.prototype.formatOnType = function (content, position, ch, options) {
     var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
     // check that the inserted character is the escape character
     if (dockerfile.getEscapeCharacter() === ch) {
         for (var _i = 0, _a = dockerfile.getComments(); _i < _a.length; _i++) {
             var comment = _a[_i];
             // ignore if we're in a comment
             if (comment.getRange().start.line === position.line) {
                 return [];
             }
         }
         var directive = dockerfile.getDirective();
         // ignore if we're in the parser directive
         if (directive && position.line === 0) {
             return [];
         }
         var document = vscode_languageserver_types_1.TextDocument.create("", "", 0, content);
         validityCheck: for (var i = document.offsetAt(position); i < content.length; i++) {
             switch (content.charAt(i)) {
                 case ' ':
                 case '\t':
                     break;
                 case '\r':
                 case '\n':
                     break validityCheck;
                 default:
                     // not escaping a newline, no need to format the next line
                     return [];
             }
         }
         var lines = [position.line + 1];
         var indentedLines = [];
         indentedLines[lines[0]] = true;
         return this.formatLines(document, document.getText(), lines, indentedLines, options);
     }
     return [];
 };
Esempio n. 6
0
 formatOnType(document, position, ch, options) {
     const dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
     // check that the inserted character is the escape character
     if (dockerfile.getEscapeCharacter() === ch) {
         for (let comment of dockerfile.getComments()) {
             // ignore if we're in a comment
             if (comment.getRange().start.line === position.line) {
                 return [];
             }
         }
         const directive = dockerfile.getDirective();
         // ignore if we're in the parser directive
         if (directive && position.line === 0) {
             return [];
         }
         const content = document.getText();
         validityCheck: for (let i = document.offsetAt(position); i < content.length; i++) {
             switch (content.charAt(i)) {
                 case ' ':
                 case '\t':
                     break;
                 case '\r':
                 case '\n':
                     break validityCheck;
                 default:
                     // not escaping a newline, no need to format the next line
                     return [];
             }
         }
         const lines = [position.line + 1];
         const indentedLines = [];
         indentedLines[lines[0]] = true;
         return this.formatLines(document, document.getText(), lines, indentedLines, options);
     }
     return [];
 }
Esempio n. 7
0
 computeProposals(document, position) {
     let buffer = document.getText();
     let offset = document.offsetAt(position);
     let dockerfile = dockerfile_ast_1.DockerfileParser.parse(buffer);
     let escapeCharacter = dockerfile.getEscapeCharacter();
     let directive = dockerfile.getDirective();
     if (directive !== null && position.line === 0) {
         let range = directive.getNameRange();
         if (position.character <= range.start.character) {
             // in whitespace before the directive's name
             return [this.createEscape(0, offset, dockerfile_ast_1.Directive.escape)];
         }
         else if (position.character <= range.end.character) {
             // in the name
             return [this.createEscape(position.character - range.start.character, offset, dockerfile_ast_1.Directive.escape)];
         }
         return [];
     }
     // directive only possible on the first line
     let comments = dockerfile.getComments();
     if (comments.length !== 0) {
         if (position.line === 0) {
             let commentRange = comments[0].getRange();
             // check if the first comment is on the first line
             if (commentRange.start.line === 0) {
                 // is the user inside the comment
                 if (commentRange.start.character < position.character) {
                     let range = comments[0].getContentRange();
                     if (range === null || position.character <= range.start.character) {
                         // in whitespace
                         return [this.createEscape(0, offset, dockerfile_ast_1.Directive.escape)];
                     }
                     let comment = comments[0].getContent();
                     if (position.character <= range.end.character) {
                         // within the content
                         let prefix = comment.substring(0, position.character - range.start.character);
                         // substring check
                         if (dockerfile_ast_1.Directive.escape.indexOf(prefix.toLowerCase()) === 0) {
                             return [this.createEscape(prefix.length, offset, dockerfile_ast_1.Directive.escape)];
                         }
                     }
                     return [];
                 }
             }
         }
         else {
             for (let comment of comments) {
                 let range = comment.getRange();
                 if (range.start.line === position.line) {
                     if (range.start.character < position.character && position.character <= range.end.character) {
                         // inside a comment
                         return [];
                     }
                 }
             }
         }
     }
     let prefix = DockerAssist.calculateTruePrefix(buffer, offset, escapeCharacter);
     if (prefix !== "") {
         let index = prefix.lastIndexOf('$');
         // $ exists so we're at a variable
         if (index !== -1) {
             // check that the variable $ wasn't escaped
             if (prefix.charAt(index - 1) !== '\\') {
                 // get the variable's prefix thus far
                 var variablePrefix = prefix.substring(index + 1).toLowerCase();
                 let prefixLength = variablePrefix.length + 1;
                 const items = [];
                 if (variablePrefix === "") {
                     // empty prefix, return all variables
                     for (let variable of dockerfile.getAvailableVariables(position.line)) {
                         let doc = dockerfile.resolveVariable(variable, position.line);
                         items.push(this.createVariableCompletionItem(variable, prefixLength, offset, true, doc));
                     }
                     for (let variable of dockerfile_ast_1.DefaultVariables) {
                         let doc = dockerfile.resolveVariable(variable, position.line);
                         items.push(this.createVariableCompletionItem(variable, prefixLength, offset, true, doc));
                     }
                 }
                 else {
                     let brace = false;
                     if (variablePrefix.charAt(0) === '{') {
                         brace = true;
                         variablePrefix = variablePrefix.substring(1);
                     }
                     for (let variable of dockerfile.getAvailableVariables(position.line)) {
                         if (variable.toLowerCase().indexOf(variablePrefix) === 0) {
                             let doc = dockerfile.resolveVariable(variable, position.line);
                             items.push(this.createVariableCompletionItem(variable, prefixLength, offset, brace, doc));
                         }
                     }
                     for (let variable of dockerfile_ast_1.DefaultVariables) {
                         if (variable.toLowerCase().indexOf(variablePrefix) === 0) {
                             let doc = dockerfile.resolveVariable(variable, position.line);
                             items.push(this.createVariableCompletionItem(variable, prefixLength, offset, brace, doc));
                         }
                     }
                 }
                 items.sort((a, b) => {
                     if (a.label.toLowerCase() === b.label.toLowerCase()) {
                         // put uppercase variables first
                         return a.label.localeCompare(b.label) * -1;
                     }
                     return a.label.localeCompare(b.label);
                 });
                 return items;
             }
         }
     }
     let previousWord = "";
     instructionsCheck: for (let instruction of dockerfile.getInstructions()) {
         if (docker_1.Util.isInsideRange(position, instruction.getInstructionRange())) {
             break;
         }
         else if (docker_1.Util.isInsideRange(position, instruction.getRange())) {
             switch (instruction.getKeyword()) {
                 case "ADD":
                     return this.createAddProposals(instruction, position, offset, prefix);
                 case "COPY":
                     return this.createCopyProposals(dockerfile, instruction, position, offset, prefix);
                 case "FROM":
                     return this.createFromProposals(instruction, position, prefix);
                 case "HEALTHCHECK":
                     let subcommand = instruction.getSubcommand();
                     if (subcommand && subcommand.isBefore(position)) {
                         return [];
                     }
                     return this.createHealthcheckProposals(offset, prefix);
                 case "ONBUILD":
                     let onbuildArgs = instruction.getArguments();
                     if (onbuildArgs.length === 0 || docker_1.Util.isInsideRange(position, onbuildArgs[0].getRange())) {
                         // no trigger instructions or the cursor is in the trigger instruction
                         previousWord = "ONBUILD";
                         break instructionsCheck;
                     }
                     else {
                         let trigger = instruction.getTriggerInstruction();
                         switch (trigger.getKeyword()) {
                             case "ADD":
                                 return this.createAddProposals(trigger, position, offset, prefix);
                             case "COPY":
                                 return this.createCopyProposals(dockerfile, trigger, position, offset, prefix);
                             case "HEALTHCHECK":
                                 let subcommand = trigger.getSubcommand();
                                 if (subcommand && subcommand.isBefore(position)) {
                                     return [];
                                 }
                                 return this.createHealthcheckProposals(offset, prefix);
                         }
                     }
                     return [];
                 default:
                     return [];
             }
         }
     }
     if (prefix === "") {
         if (dockerfile.getInstructions().length === 0) {
             // if we don't have any instructions, only suggest FROM
             return [this.createFROM(0, offset, "FROM")];
         }
         // no prefix, return all the proposals
         return this.createProposals(docker_1.KEYWORDS, previousWord, 0, offset);
     }
     const suggestions = [];
     var uppercasePrefix = prefix.toUpperCase();
     for (let i = 0; i < docker_1.KEYWORDS.length; i++) {
         if (docker_1.KEYWORDS[i] === uppercasePrefix) {
             // prefix is a keyword already, nothing to suggest
             return [];
         }
         else if (docker_1.KEYWORDS[i].indexOf(uppercasePrefix) === 0) {
             suggestions.push(docker_1.KEYWORDS[i]);
         }
     }
     if (suggestions.length === 0) {
         // prefix doesn't match any keywords, nothing to suggest
         return [];
     }
     return this.createProposals(suggestions, previousWord, prefix.length, offset);
 }
Esempio n. 8
0
 computeHighlightRanges(document, position) {
     let dockerfile = dockerfile_ast_1.DockerfileParser.parse(document.getText());
     let provider = new dockerDefinition_1.DockerDefinition();
     let location = provider.computeDefinition(document, position);
     let image = location === null ? dockerfile.getContainingImage(position) : dockerfile.getContainingImage(location.range.start);
     const highlights = [];
     if (location === null) {
         for (let instruction of dockerfile.getCOPYs()) {
             let flag = instruction.getFromFlag();
             if (flag) {
                 let range = flag.getValueRange();
                 if (range && range.start.line === position.line && range.start.character <= position.character && position.character <= range.end.character) {
                     let stage = flag.getValue();
                     for (let other of dockerfile.getCOPYs()) {
                         let otherFlag = other.getFromFlag();
                         if (otherFlag && otherFlag.getValue() === stage) {
                             highlights.push(vscode_languageserver_1.DocumentHighlight.create(otherFlag.getValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                         }
                     }
                     return highlights;
                 }
             }
         }
         for (const from of dockerfile.getFROMs()) {
             for (const variable of from.getVariables()) {
                 if (docker_1.Util.isInsideRange(position, variable.getNameRange())) {
                     const name = variable.getName();
                     for (const loopFrom of dockerfile.getFROMs()) {
                         for (const fromVariable of loopFrom.getVariables()) {
                             if (fromVariable.getName() === name) {
                                 highlights.push(vscode_languageserver_1.DocumentHighlight.create(fromVariable.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                             }
                         }
                     }
                     return highlights;
                 }
             }
         }
         for (let instruction of image.getInstructions()) {
             for (let variable of instruction.getVariables()) {
                 if (docker_1.Util.isInsideRange(position, variable.getNameRange())) {
                     let name = variable.getName();
                     for (let instruction of image.getInstructions()) {
                         if (!(instruction instanceof dockerfile_ast_1.From)) {
                             for (let variable of instruction.getVariables()) {
                                 if (variable.getName() === name) {
                                     highlights.push(vscode_languageserver_1.DocumentHighlight.create(variable.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                                 }
                             }
                         }
                     }
                     return highlights;
                 }
             }
         }
     }
     else {
         let definition = document.getText().substring(document.offsetAt(location.range.start), document.offsetAt(location.range.end));
         for (let from of dockerfile.getFROMs()) {
             let range = from.getBuildStageRange();
             if (range && range.start.line === location.range.start.line) {
                 highlights.push(vscode_languageserver_1.DocumentHighlight.create(location.range, vscode_languageserver_1.DocumentHighlightKind.Write));
                 for (let instruction of dockerfile.getCOPYs()) {
                     let flag = instruction.getFromFlag();
                     if (flag) {
                         if (flag.getValue() === definition) {
                             highlights.push(vscode_languageserver_1.DocumentHighlight.create(flag.getValueRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                         }
                     }
                 }
                 return highlights;
             }
         }
         for (let arg of image.getARGs()) {
             let property = arg.getProperty();
             // property may be null if it's an ARG with no arguments
             if (property && property.getName() === definition) {
                 highlights.push(vscode_languageserver_1.DocumentHighlight.create(property.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Write));
             }
         }
         for (let env of image.getENVs()) {
             for (let property of env.getProperties()) {
                 if (property.getName() === definition) {
                     highlights.push(vscode_languageserver_1.DocumentHighlight.create(property.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Write));
                 }
             }
         }
         for (let instruction of image.getInstructions()) {
             // only highlight variables in non-FROM instructions
             if (!(instruction instanceof dockerfile_ast_1.From)) {
                 for (const variable of instruction.getVariables()) {
                     if (variable.getName() === definition) {
                         highlights.push(vscode_languageserver_1.DocumentHighlight.create(variable.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                     }
                 }
             }
         }
         for (const arg of dockerfile.getInitialARGs()) {
             const property = arg.getProperty();
             if (property && docker_1.Util.rangeEquals(property.getNameRange(), location.range)) {
                 for (const from of dockerfile.getFROMs()) {
                     for (const variable of from.getVariables()) {
                         if (variable.getName() === definition) {
                             highlights.push(vscode_languageserver_1.DocumentHighlight.create(variable.getNameRange(), vscode_languageserver_1.DocumentHighlightKind.Read));
                         }
                     }
                 }
             }
         }
     }
     return highlights;
 }
Esempio n. 9
0
 DockerDefinition.prototype.computeDefinitionRange = function (content, position) {
     var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content);
     var range = this.computeBuildStageDefinition(dockerfile, position);
     return range ? range : this.computeVariableDefinition(dockerfile, position);
 };