Skip to content

Commit

Permalink
Use Visitor in TerraformParserResult, other cleanups.
Browse files Browse the repository at this point in the history
  • Loading branch information
lkishalmi committed Aug 21, 2023
1 parent 51c6ce2 commit 38cc33f
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.netbeans.modules.csl.spi.ParserResult;
import org.netbeans.modules.languages.hcl.ast.HCLBlockFactory;
import org.netbeans.modules.languages.hcl.ast.HCLDocument;
import org.netbeans.modules.languages.hcl.ast.HCLElement;
import org.netbeans.modules.languages.hcl.grammar.HCLLexer;
import org.netbeans.modules.languages.hcl.grammar.HCLParser;
import org.netbeans.modules.languages.hcl.grammar.HCLParserBaseListener;
Expand Down Expand Up @@ -141,6 +142,15 @@ protected void configureParser(HCLParser parser) {
protected void processDocument(HCLDocument doc, SourceRef references) {
}

protected void addError(HCLElement e, String message) {
references.getOffsetRange(e).ifPresent((range) -> addError(message, range));
}

private void addError(String message, OffsetRange range) {
DefaultError error = new DefaultError(null, message, null, getFileObject(), range.getStart() , range.getEnd(), false, Severity.ERROR);
errors.add(error);
}

private void addFold(FoldType ft, Token token) {
if (token.getText().contains("\n") && (token.getStartIndex() < token.getStopIndex())) {
List<OffsetRange> foldBag = folds.computeIfAbsent(ft.code(), (t) -> new ArrayList<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,15 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.csl.api.Severity;
import org.netbeans.modules.csl.spi.DefaultError;
import org.netbeans.modules.languages.hcl.HCLParserResult;
import org.netbeans.modules.languages.hcl.ast.HCLAttribute;
import org.netbeans.modules.languages.hcl.ast.HCLBlock;
import org.netbeans.modules.languages.hcl.ast.HCLContainer;
import org.netbeans.modules.languages.hcl.ast.HCLDocument;
import org.netbeans.modules.languages.hcl.ast.HCLIdentifier;
import org.netbeans.modules.languages.hcl.SourceRef;
import org.netbeans.modules.languages.hcl.ast.HCLElement;
import org.netbeans.modules.languages.hcl.ast.HCLElement.Visitor;
import org.netbeans.modules.parsing.api.Snapshot;
import org.openide.util.NbBundle.Messages;

Expand All @@ -42,7 +41,8 @@
*/
public class TerraformParserResult extends HCLParserResult {


private Map<String, HCLBlock> definedBlocks = new HashMap<>();

public enum BlockType {

CHECK("check", 2),
Expand Down Expand Up @@ -97,55 +97,66 @@ public TerraformParserResult(Snapshot snapshot) {

})
protected void processDocument(HCLDocument doc, SourceRef references) {
Set<String> defined = new HashSet<>();
for (HCLBlock block : doc.getBlocks()) {
List<HCLIdentifier> decl = block.getDeclaration();
HCLIdentifier type = decl.get(0);

BlockType bt = BlockType.get(type.id());
if (bt != null) {
if (decl.size() != bt.definitionLength) {
references.getOffsetRange(type).ifPresent((range) -> addError(Bundle.INVALID_BLOCK_DECLARATION(bt.type, bt.definitionLength - 1), range));
} else {
if (!defined.add(block.id())) {
switch (bt) {
case CHECK:
case DATA:
case MODULE:
case OUTPUT:
case RESOURCE:
case VARIABLE:
references.getOffsetRange(type).ifPresent((range) -> addError(Bundle.DUPLICATE_BLOCK(block.id()), range));
doc.accept(this::duplicateAttributeVisitor);
doc.accept(this::checkBlockDeclarationVisitor);
}


private boolean checkBlockDeclarationVisitor(HCLElement e) {
if (e instanceof HCLBlock) {
HCLBlock block = (HCLBlock) e;
if (block.getParent() instanceof HCLDocument) {
List<HCLIdentifier> decl = block.getDeclaration();
HCLIdentifier type = decl.get(0);

BlockType bt = BlockType.get(type.id());
if (bt != null) {
if (decl.size() != bt.definitionLength) {
addError(type, Bundle.INVALID_BLOCK_DECLARATION(bt.type, bt.definitionLength - 1));
} else {
if (definedBlocks.put(block.id(), block) != null) {
switch (bt) {
case CHECK:
case DATA:
case MODULE:
case OUTPUT:
case RESOURCE:
case VARIABLE:
addError(decl.get(bt.definitionLength - 1), Bundle.DUPLICATE_BLOCK(block.id()));
}
}
}
} else {
addError(type, Bundle.UNKNOWN_BLOCK(type.id()));
}
} else {
references.getOffsetRange(type).ifPresent((range) -> addError(Bundle.UNKNOWN_BLOCK(type.id()), range));
}
checkDuplicateAttribute(block, references);
}
for (HCLAttribute attribute : doc.getAttributes()) {
references.getOffsetRange(attribute.getName()).ifPresent((range) -> addError(Bundle.UNEXPECTED_DOCUMENT_ATTRIBUTE(attribute.id()), range));
return true;
}
return !(e instanceof HCLDocument);
}

private void checkDuplicateAttribute(HCLContainer c, SourceRef references) {
for (HCLBlock block : c.getBlocks()) {
checkDuplicateAttribute(block, references);

private boolean duplicateAttributeVisitor(HCLElement e) {
if (e instanceof HCLDocument) {
HCLDocument doc = (HCLDocument) e;
for (HCLAttribute attr : doc.getAttributes()) {
addError(attr, Bundle.UNEXPECTED_DOCUMENT_ATTRIBUTE(attr.id()));
}
return false;
}
if (c.hasAttributes()) {
Set<String> defined = new HashSet<>();
for (HCLAttribute attr : c.getAttributes()) {
if (!defined.add(attr.id())) {
references.getOffsetRange(attr.getName()).ifPresent((range) -> addError(Bundle.DUPLICATE_ATTRIBUTE(attr.id()), range));
if (e instanceof HCLContainer) {
HCLContainer c = (HCLContainer) e;
if (c.hasAttributes()) {
Set<String> defined = new HashSet<>();
for (HCLAttribute attr : c.getAttributes()) {
if (!defined.add(attr.id())) {
addError(attr.getName(), Bundle.DUPLICATE_ATTRIBUTE(attr.id()));
}
}
}
return false;
}
return true;
}

private void addError(String message, OffsetRange range) {
DefaultError error = new DefaultError(null, message, null, getFileObject(), range.getStart() , range.getEnd(), false, Severity.ERROR);
errors.add(error);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected boolean visitBlock(HCLBlock block) {
protected boolean visitExpression(HCLExpression expr) {
if (expr instanceof HCLResolveOperation.Attribute) {
HCLResolveOperation.Attribute attr = (HCLResolveOperation.Attribute) expr;
if (attr.base instanceof HCLVariable) {
if ((rootBlockType != null) && (attr.base instanceof HCLVariable)) {
String name = ((HCLVariable)attr.base).name.id;
switch (rootBlockType) {
case CHECK:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

import java.util.HashSet;
import java.util.Set;
import org.netbeans.modules.csl.api.Severity;
import org.netbeans.modules.csl.spi.DefaultError;
import org.netbeans.modules.languages.hcl.HCLParserResult;
import org.netbeans.modules.languages.hcl.ast.HCLAttribute;
import org.netbeans.modules.languages.hcl.ast.HCLBlock;
Expand All @@ -44,22 +42,16 @@ public TFVarsParserResult(Snapshot snapshot) {
@NbBundle.Messages({
"INVALID_BLOCK=Blocks are not supported in TFVars files.",
"# {0} - The name of duplicated variable",
"DUPLICATE_VARIABLE=Valiable {0} is already defined."
"DUPLICATE_VARIABLE=Variable {0} is already defined."
})
protected void processDocument(HCLDocument doc, SourceRef references) {
for (HCLBlock block : doc.getBlocks()) {
references.getOffsetRange(block).ifPresent((range) -> {
DefaultError error = new DefaultError(null, Bundle.INVALID_BLOCK(), null, getFileObject(), range.getStart() , range.getEnd(), Severity.ERROR);
errors.add(error);
});
addError(block, Bundle.INVALID_BLOCK());
}
Set<String> usedAttributes = new HashSet<>();
for (HCLAttribute attr : doc.getAttributes()) {
if (!usedAttributes.add(attr.id())) {
references.getOffsetRange(attr.getName()).ifPresent((range) -> {
DefaultError error = new DefaultError(null, Bundle.DUPLICATE_VARIABLE(attr.id()), null, getFileObject(), range.getStart() , range.getEnd(), Severity.ERROR);
errors.add(error);
});
addError(attr.getName(), Bundle.DUPLICATE_VARIABLE(attr.id()));
}
}
}
Expand Down

0 comments on commit 38cc33f

Please sign in to comment.