Skip to content

Commit

Permalink
Always validate file if langid=ARM (#285)
Browse files Browse the repository at this point in the history
* Always validate file if langid=ARM

* refactor
  • Loading branch information
StephenWeatherford authored Sep 10, 2019
1 parent 9e2c499 commit 44cad34
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 65 deletions.
136 changes: 76 additions & 60 deletions src/AzureRMTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { startArmLanguageServer, stopArmLanguageServer } from "./languageclient/
import { PositionContext } from "./PositionContext";
import * as Reference from "./Reference";
import { Stopwatch } from "./Stopwatch";
import { armDeploymentDocumentSelector, mightBeDeploymentTemplate, shouldWatchDocument } from "./supported";
import { armDeploymentDocumentSelector, mightBeDeploymentTemplate } from "./supported";
import * as TLE from "./TLE";
import { JsonOutlineProvider } from "./Treeview";
import { UnrecognizedFunctionIssue } from "./UnrecognizedFunctionIssue";
Expand Down Expand Up @@ -122,72 +122,56 @@ export class AzureRMTools {
actionContext.telemetry.properties.isActivationEvent = 'true';
actionContext.telemetry.properties.fileExt = path.extname(document.fileName);

let foundDeploymentTemplate = false;

if (shouldWatchDocument(document)) {
if (mightBeDeploymentTemplate(document)) {
// If the documentUri is not in our dictionary of deployment templates, then we
// know that this document was just opened (as opposed to changed/updated).
let stopwatch: Stopwatch;
const documentUri: string = document.uri.toString();
if (!this._deploymentTemplates[documentUri]) {
stopwatch = new Stopwatch();
stopwatch.start();
}
const stopwatch = new Stopwatch();
stopwatch.start();

let treatAsDeploymentTemplate = false;
let isNewlyOpened = false; // As opposed to already opened and being activated

if (document.languageId === armDeploymentLanguageId) {
// Lang ID is set to ARM, whether auto or manual, respect the setting
treatAsDeploymentTemplate = true;
}

let shouldParseFile = treatAsDeploymentTemplate || mightBeDeploymentTemplate(document);
if (shouldParseFile) {
// If the documentUri is not in our dictionary of deployment templates, then we
// know that this document was just opened (as opposed to changed/updated).
const documentUri: string = document.uri.toString();
if (!this._deploymentTemplates[documentUri]) {
isNewlyOpened = true;
}

// Do a full parse
let deploymentTemplate: DeploymentTemplate = new DeploymentTemplate(document.getText(), documentUri);
if (deploymentTemplate.hasArmSchemaUri()) {
treatAsDeploymentTemplate = true;
}
actionContext.telemetry.measurements.parseDurationInMilliseconds = stopwatch.duration.totalMilliseconds;

if (treatAsDeploymentTemplate) {
this.ensureDeploymentTemplateEventsHookedUp();
this._deploymentTemplates[documentUri] = deploymentTemplate;

// Might be a deployment template, need to do a full parse to make sure
let deploymentTemplate: DeploymentTemplate = new DeploymentTemplate(document.getText(), documentUri);
if (deploymentTemplate.hasArmSchemaUri()) {
foundDeploymentTemplate = true;

this.ensureDeploymentTemplateEventsHookedUp();

this._deploymentTemplates[documentUri] = deploymentTemplate;

// We only initialized the stopwatch if the deployment template was being
// opened. The stopwatch variable will not be initialized if the deployment
// template is being edited.
if (stopwatch) {
// A deployment template has been opened (as opposed to having been tabbed to)

stopwatch.stop();

// Set the language ID to ARM deployment template
if (document.languageId !== armDeploymentLanguageId) {
vscode.languages.setTextDocumentLanguage(document, armDeploymentLanguageId);

// The document will be reloaded, firing this event again with the new langid
actionContext.telemetry.properties.switchedToArm = 'true';
actionContext.telemetry.properties.docLangId = document.languageId;
actionContext.telemetry.properties.docExtension = path.extname(document.fileName);
actionContext.telemetry.suppressIfSuccessful = false;
return;
}

ext.reporter.sendTelemetryEvent(
"Deployment Template Opened",
{
docLangId: document.languageId,
docExtension: path.extname(document.fileName),
},
{
documentSizeInCharacters: document.getText().length,
parseDurationInMilliseconds: stopwatch.duration.totalMilliseconds,
lineCount: deploymentTemplate.lineCount,
paramsCount: deploymentTemplate.parameterDefinitions.length,
varsCount: deploymentTemplate.variableDefinitions.length,
namespacesCount: deploymentTemplate.namespaceDefinitions.length
});

this.logFunctionCounts(deploymentTemplate);
if (isNewlyOpened) {
// A deployment template has been opened (as opposed to having been tabbed to)

// Make sure the language ID is set to ARM deployment template
if (document.languageId !== armDeploymentLanguageId) {
// The document will be reloaded, firing this event again with the new langid
AzureRMTools.setLanguageToArm(document, actionContext);
return;
}

this.reportDeploymentTemplateErrors(document, deploymentTemplate);
// Template for template opened
this.reportTemplateOpenedTelemetry(document, deploymentTemplate, stopwatch);
}

this.reportDeploymentTemplateErrors(document, deploymentTemplate);
}
}

if (!foundDeploymentTemplate) {
if (!treatAsDeploymentTemplate) {
// If the document is not a deployment template, then we need
// to remove it from our deployment template cache. It doesn't
// matter if the document is a JSON file and was never a
Expand All @@ -201,6 +185,38 @@ export class AzureRMTools {
});
}

private static setLanguageToArm(document: vscode.TextDocument, actionContext: IActionContext): void {
vscode.languages.setTextDocumentLanguage(document, armDeploymentLanguageId);

actionContext.telemetry.properties.switchedToArm = 'true';
actionContext.telemetry.properties.docLangId = document.languageId;
actionContext.telemetry.properties.docExtension = path.extname(document.fileName);
actionContext.telemetry.suppressIfSuccessful = false;
}

private reportTemplateOpenedTelemetry(
document: vscode.TextDocument,
deploymentTemplate: DeploymentTemplate,
stopwatch: Stopwatch
): void {
ext.reporter.sendTelemetryEvent(
"Deployment Template Opened",
{
docLangId: document.languageId,
docExtension: path.extname(document.fileName),
},
{
documentSizeInCharacters: document.getText().length,
parseDurationInMilliseconds: stopwatch.duration.totalMilliseconds,
lineCount: deploymentTemplate.lineCount,
paramsCount: deploymentTemplate.parameterDefinitions.length,
varsCount: deploymentTemplate.variableDefinitions.length,
namespacesCount: deploymentTemplate.namespaceDefinitions.length
});

this.logFunctionCounts(deploymentTemplate);
}

private reportDeploymentTemplateErrors(document: vscode.TextDocument, deploymentTemplate: DeploymentTemplate): void {
// Don't wait
// tslint:disable-next-line: no-floating-promises
Expand Down
8 changes: 4 additions & 4 deletions src/Treeview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class JsonOutlineProvider implements vscode.TreeDataProvider<string> {
public getChildren(element?: string): string[] {
// check if there is a visible text editor
if (vscode.window.visibleTextEditors.length > 0) {
if (vscode.window.activeTextEditor && this.isArmTemplateDocument(vscode.window.activeTextEditor.document)) {
if (vscode.window.activeTextEditor && this.shouldShowTreeForDocument(vscode.window.activeTextEditor.document)) {

if (!this.tree) {
this.refresh();
Expand Down Expand Up @@ -148,7 +148,7 @@ export class JsonOutlineProvider implements vscode.TreeDataProvider<string> {
}

private parseTree(document?: vscode.TextDocument): void {
if (this.isArmTemplateDocument(document)) {
if (this.shouldShowTreeForDocument(document)) {
this.text = document.getText();
this.tree = Json.parse(this.text);
}
Expand Down Expand Up @@ -342,7 +342,7 @@ export class JsonOutlineProvider implements vscode.TreeDataProvider<string> {
const activeEditor: vscode.TextEditor = vscode.window.activeTextEditor;
const document: vscode.TextDocument = !!activeEditor ? activeEditor.document : null;
this.parseTree(document);
const showTreeView = this.isArmTemplateDocument(document);
const showTreeView = this.shouldShowTreeForDocument(document);

if (showTreeView) {
this.refresh();
Expand All @@ -351,7 +351,7 @@ export class JsonOutlineProvider implements vscode.TreeDataProvider<string> {
this.setTreeViewContext(showTreeView);
}

private isArmTemplateDocument(document?: vscode.TextDocument): boolean {
private shouldShowTreeForDocument(document?: vscode.TextDocument): boolean {
// Only show view if the language is set to ARM Deployment Template
return !!document && document.languageId === armDeploymentLanguageId;
}
Expand Down
2 changes: 1 addition & 1 deletion src/supported.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function isJsonOrJsoncLangId(textDocument: TextDocument): boolean {

// We keep track of arm-deployment files, of course,
// but also JSON/JSONC (unless auto-detect is disabled) so we can check them for the ARM schema
export function shouldWatchDocument(textDocument: TextDocument): boolean {
function shouldWatchDocument(textDocument: TextDocument): boolean {
if (textDocument.uri.scheme !== 'file') {
return false;
}
Expand Down

0 comments on commit 44cad34

Please sign in to comment.