/* * Copyright 2016 The Bazel Authors. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.idea.blaze.base.lang.buildfile.psi.util; import com.google.idea.blaze.base.lang.buildfile.language.BuildFileLanguage; import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType; import com.google.idea.blaze.base.lang.buildfile.lexer.BuildToken; import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind; import com.google.idea.blaze.base.lang.buildfile.psi.Argument; import com.google.idea.blaze.base.lang.buildfile.psi.Expression; import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression; import com.google.idea.blaze.base.lang.buildfile.psi.Statement; import com.intellij.lang.ASTNode; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; import com.intellij.psi.impl.PsiFileFactoryImpl; import com.intellij.testFramework.LightVirtualFile; import javax.annotation.Nullable; /** Creates dummy BuildElements, e.g. for renaming purposes. */ public class BuildElementGenerator { public static BuildElementGenerator getInstance(Project project) { return ServiceManager.getService(project, BuildElementGenerator.class); } private static final String DUMMY_FILENAME = "dummy.bzl"; private final Project project; public BuildElementGenerator(Project project) { this.project = project; } public PsiFile createDummyFile(String contents) { PsiFileFactory factory = PsiFileFactory.getInstance(project); LightVirtualFile virtualFile = new LightVirtualFile(DUMMY_FILENAME, BuildFileType.INSTANCE, contents); PsiFile psiFile = ((PsiFileFactoryImpl) factory) .trySetupPsiForFile(virtualFile, BuildFileLanguage.INSTANCE, false, true); assert psiFile != null; return psiFile; } public ASTNode createNameIdentifier(String name) { PsiFile dummyFile = createDummyFile(name); ASTNode referenceNode = dummyFile.getNode().getFirstChildNode(); ASTNode nameNode = referenceNode.getFirstChildNode(); if (nameNode.getElementType() != BuildToken.IDENTIFIER) { throw new RuntimeException( "Expecting an IDENTIFIER node directly below the BuildFile PSI element"); } return nameNode; } public ASTNode createStringNode(String contents) { PsiFile dummyFile = createDummyFile('"' + contents + '"'); ASTNode literalNode = dummyFile.getNode().getFirstChildNode(); ASTNode stringNode = literalNode.getFirstChildNode(); assert (stringNode.getElementType() == BuildToken.fromKind(TokenKind.STRING)); return stringNode; } public Argument.Keyword createKeywordArgument(String keyword, String value) { String dummyText = String.format("foo(%s = \"%s\")", keyword, value); FuncallExpression funcall = (FuncallExpression) createExpressionFromText(dummyText); return (Argument.Keyword) funcall.getArguments()[0]; } public Expression createExpressionFromText(String text) { PsiFile dummyFile = createDummyFile(text); PsiElement element = dummyFile.getFirstChild(); if (element instanceof Expression) { return (Expression) element; } throw new RuntimeException("Could not parse text as expression: '" + text + "'"); } /** Returns null if the text can't be parsed as a statement. */ @Nullable public Statement createStatementFromText(String text) { PsiFile dummyFile = createDummyFile(text); PsiElement element = dummyFile.getFirstChild(); if (element instanceof Statement) { return (Statement) element; } return null; } }