Skip to content

Commit

Permalink
Guard against read/write mismatch in stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
KronicDeth committed Aug 7, 2017
1 parent ee23546 commit 136af95
Show file tree
Hide file tree
Showing 44 changed files with 594 additions and 633 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://www.jetbrains.com/intellij-repository/releases
# https://www.jetbrains.com/intellij-repository/snapshots

version = 5.1.0
version = 6.0.0
ideaVersion = 2017.1.5
javaVersion = 1.8
javaTargetVersion = 1.6
Expand Down
28 changes: 28 additions & 0 deletions src/org/elixir_lang/beam/psi/impl/CallDefinitionStubImpl.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.elixir_lang.beam.psi.impl;

import com.intellij.util.io.StringRef;
import org.elixir_lang.beam.psi.CallDefinition;
import org.elixir_lang.beam.psi.stubs.CallDefinitionStub;
import org.elixir_lang.beam.psi.stubs.ModuleStub;
import org.elixir_lang.beam.psi.stubs.ModuleStubElementTypes;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

import static org.elixir_lang.psi.call.name.Module.KERNEL;

/**
Expand Down Expand Up @@ -35,6 +39,30 @@ public class CallDefinitionStubImpl<T extends CallDefinition> extends StubbicBas
*/
private final int callDefinitionClauseHeadArity;

public CallDefinitionStubImpl(@NotNull ModuleStub parentStub,
@NotNull Deserialized deserialized,
int callDefinitionClauseHeadArity) {
super(parentStub, ModuleStubElementTypes.CALL_DEFINITION, deserialized.name.toString());

StringRef resolvedModuleName = deserialized.resolvedModuleName;
assert resolvedModuleName != null;
assert resolvedModuleName.toString().equals(RESOLVED_MODULE_NAME);

StringRef resolvedFunctionName = deserialized.resolvedFunctionName;
assert resolvedFunctionName != null;

this.resolvedFunctionName = resolvedFunctionName.toString();

assert deserialized.resolvedFinalArity == RESOLVED_FINAL_ARITY;

assert deserialized.hasDoBlockOrKeyword == HAS_DO_BLOCK_OR_KEYWORD;

Set<StringRef> canonicalNameSet = deserialized.canonicalNameSet;
assert canonicalNameSet.size() == 1;
assert canonicalNameSet.iterator().next().toString().equals(this.getName());

this.callDefinitionClauseHeadArity = callDefinitionClauseHeadArity;
}

public CallDefinitionStubImpl(@NotNull ModuleStub parentStub,
@NotNull String macro,
Expand Down
31 changes: 28 additions & 3 deletions src/org/elixir_lang/beam/psi/impl/ModuleStubImpl.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
package org.elixir_lang.beam.psi.impl;

import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.elixir_lang.beam.psi.Module;
import org.elixir_lang.beam.psi.stubs.ModuleStub;
import org.elixir_lang.beam.psi.stubs.ModuleStubElementTypes;
import org.elixir_lang.psi.call.name.Function;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;

import static org.elixir_lang.psi.call.name.Function.DEFMODULE;
import static org.elixir_lang.psi.call.name.Module.KERNEL;

/**
* See {@link com.intellij.psi.impl.java.stubs.impl.PsiClassStubImpl}
*/
public class ModuleStubImpl<T extends Module> extends StubbicBase<T> implements ModuleStub<T> {
public static final int RESOLVED_FINAL_ARITY = 2;
public static final String RESOLVED_FUNCTION_NAME = DEFMODULE;
public static final String RESOLVED_MODULE_NAME = KERNEL;
private static final int RESOLVED_FINAL_ARITY = 2;
private static final String RESOLVED_FUNCTION_NAME = DEFMODULE;
private static final String RESOLVED_MODULE_NAME = KERNEL;

public ModuleStubImpl(@NotNull StubElement parentStub,
@NotNull String name) {
super(parentStub, ModuleStubElementTypes.MODULE, name);
}

public ModuleStubImpl(@NotNull StubElement parentStub,
@NotNull Deserialized deserialized) {
super(parentStub, ModuleStubElementTypes.MODULE, deserialized.name.toString());

StringRef resolvedModuleName = deserialized.resolvedModuleName;
assert resolvedModuleName != null;
assert resolvedModuleName.getString().equals(RESOLVED_MODULE_NAME);

StringRef resolvedFunctionName = deserialized.resolvedFunctionName;
assert resolvedFunctionName != null;
assert resolvedFunctionName.toString().equals(RESOLVED_FUNCTION_NAME);

assert deserialized.resolvedFinalArity == RESOLVED_FINAL_ARITY;

assert deserialized.hasDoBlockOrKeyword == HAS_DO_BLOCK_OR_KEYWORD;

Set<StringRef> canonicalNameSet = deserialized.canonicalNameSet;
assert canonicalNameSet.size() == 1;
assert canonicalNameSet.iterator().next().toString().equals(this.getName());
}

/**
* Arity of {@code defmodule .. do}.
*
Expand Down
8 changes: 4 additions & 4 deletions src/org/elixir_lang/beam/psi/stubs/ModuleElementType.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import com.intellij.lang.LighterASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.*;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.elixir_lang.psi.stub.call.Stubbic;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

import static org.elixir_lang.psi.stub.type.Named.indexStubbic;
import static org.elixir_lang.psi.stub.type.call.Stub.serializeStubbic;

/**
*
Expand Down Expand Up @@ -60,12 +60,12 @@ public P createPsi(@NotNull ASTNode node) {
* Serializes {@code stub} as a {@link Stubbic}.
*
* @param stub created by {@link org.elixir_lang.beam.psi.BeamFileImpl#buildFileStub(byte[], String)}
* @param dataStream stream to write {@code stub} to
* @param stubOutputStream stream to write {@code stub} to
* @throws IOException if {@code dataStream} cannot be written to
*/
@Override
public void serialize(@NotNull S stub, @NotNull StubOutputStream dataStream) throws IOException {
serializeStubbic(stub, dataStream);
public void serialize(@NotNull S stub, @NotNull StubOutputStream stubOutputStream) throws IOException {
Deserialized.serialize(stubOutputStream, stub);
}

/**
Expand Down
58 changes: 21 additions & 37 deletions src/org/elixir_lang/beam/psi/stubs/ModuleStubElementTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.util.io.StringRef;
import org.elixir_lang.beam.psi.CallDefinition;
import org.elixir_lang.beam.psi.CallDefinitionElement;
import org.elixir_lang.beam.psi.Module;
Expand All @@ -13,12 +12,13 @@
import org.elixir_lang.beam.psi.impl.CallDefinitionStubImpl;
import org.elixir_lang.beam.psi.impl.ModuleImpl;
import org.elixir_lang.beam.psi.impl.ModuleStubImpl;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.Set;

import static org.elixir_lang.psi.stub.type.call.Stub.readNameSet;
import static org.elixir_lang.psi.stub.call.Deserialized.readGuarded;
import static org.elixir_lang.psi.stub.call.Deserialized.writeGuarded;

// See com.intellij.psi.impl.java.stubs.JavaStubElementTypes
public interface ModuleStubElementTypes {
Expand All @@ -36,31 +36,26 @@ public CallDefinition createPsi(@NotNull CallDefinitionStub stub) {

@NotNull
@Override
public CallDefinitionStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
assert dataStream.readName().toString().equals(CallDefinitionStubImpl.RESOLVED_MODULE_NAME);
public CallDefinitionStub deserialize(@NotNull StubInputStream stubInputStream,
@NotNull StubElement parentStub) throws IOException {
Deserialized deserialized = Deserialized.deserialize(stubInputStream);
int callDefinitionClauseArity = deserializeCallDefinitionClauseArity(stubInputStream);

String macro = dataStream.readName().toString();

assert dataStream.readVarInt() == CallDefinitionStubImpl.RESOLVED_FINAL_ARITY;
assert dataStream.readBoolean() == CallDefinitionStubImpl.HAS_DO_BLOCK_OR_KEYWORD;

StringRef nameRef = dataStream.readName();
String name = nameRef.toString();

Set<StringRef> canonicalNameRefSet = readNameSet(dataStream);

assert canonicalNameRefSet.size() == 1;
assert canonicalNameRefSet.iterator().next().toString().equals(name);

int callDefinitionClauseArity = dataStream.readVarInt();
return new CallDefinitionStubImpl((ModuleStub) parentStub, deserialized, callDefinitionClauseArity);
}

return new CallDefinitionStubImpl((ModuleStub) parentStub, macro, name, callDefinitionClauseArity);
int deserializeCallDefinitionClauseArity(@NotNull StubInputStream stubInputStream) throws IOException {
return readGuarded(stubInputStream, StubInputStream::readVarInt);
}

@Override
public void serialize(@NotNull CallDefinitionStub stub, @NotNull StubOutputStream dataStream) throws IOException {
super.serialize(stub, dataStream);
dataStream.writeVarInt(stub.callDefinitionClauseHeadArity());
public void serialize(@NotNull CallDefinitionStub stub,
@NotNull StubOutputStream stubOutputStream) throws IOException {
super.serialize(stub, stubOutputStream);
writeGuarded(
stubOutputStream,
guardedStubOutputStream -> guardedStubOutputStream.writeVarInt(stub.callDefinitionClauseHeadArity())
);
}
};

Expand All @@ -81,22 +76,11 @@ public Module createPsi(@NotNull ModuleStub stub) {

@NotNull
@Override
public ModuleStub deserialize(@NotNull StubInputStream dataStream,
public ModuleStub deserialize(@NotNull StubInputStream stubInputStream,
@NotNull StubElement parentStub) throws IOException {
assert dataStream.readName().toString().equals(ModuleStubImpl.RESOLVED_MODULE_NAME);
assert dataStream.readName().toString().equals(ModuleStubImpl.RESOLVED_FUNCTION_NAME);
assert dataStream.readVarInt() == ModuleStubImpl.RESOLVED_FINAL_ARITY;
assert dataStream.readBoolean() == ModuleStubImpl.HAS_DO_BLOCK_OR_KEYWORD;

StringRef nameRef = dataStream.readName();
String name = nameRef.toString();

Set<StringRef> canonicalNameRefSet = readNameSet(dataStream);

assert canonicalNameRefSet.size() == 1;
assert canonicalNameRefSet.iterator().next().toString().equals(name);
Deserialized deserialized = Deserialized.deserialize(stubInputStream);

return new ModuleStubImpl(parentStub, name);
return new ModuleStubImpl(parentStub, deserialized);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,15 @@

import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.elixir_lang.psi.ElixirMatchedAtUnqualifiedNoParenthesesCall;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.elixir_lang.psi.stub.call.Stub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

public class MatchedAtUnqualifiedNoParenthesesCall extends Stub<ElixirMatchedAtUnqualifiedNoParenthesesCall> {
public MatchedAtUnqualifiedNoParenthesesCall(
StubElement parent,
@NotNull IStubElementType elementType,
@Nullable StringRef resolvedModuleName,
@Nullable StringRef resolvedFunctionName,
int resolvedFinalArity,
boolean hasDoBlockOrKeyword,
@NotNull StringRef name,
@NotNull Set<StringRef> canonicalNameSet
) {
super(parent,
elementType,
resolvedModuleName,
resolvedFunctionName,
resolvedFinalArity,
hasDoBlockOrKeyword,
name,
canonicalNameSet);
}

public MatchedAtUnqualifiedNoParenthesesCall(
StubElement parent,
@NotNull IStubElementType elementType,
Expand All @@ -53,4 +32,10 @@ public MatchedAtUnqualifiedNoParenthesesCall(
canonicalNameSet
);
}

public MatchedAtUnqualifiedNoParenthesesCall(StubElement parentStub,
IStubElementType elementType,
Deserialized deserialized) {
super(parentStub, elementType, deserialized);
}
}
22 changes: 3 additions & 19 deletions src/org/elixir_lang/psi/stub/MatchedDotCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,20 @@

import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.elixir_lang.psi.ElixirMatchedDotCall;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.elixir_lang.psi.stub.call.Stub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

public class MatchedDotCall extends Stub<ElixirMatchedDotCall> {
public MatchedDotCall(
StubElement parent,
@NotNull IStubElementType elementType,
@Nullable StringRef resolvedModuleName,
@Nullable StringRef resolvedFunctionName,
int resolvedFinalArity,
boolean hasDoBlockOrKeyword,
@NotNull StringRef name,
@NotNull Set<StringRef> canonicalNameSet
) {
super(
parent,
elementType,
resolvedModuleName,
resolvedFunctionName,
resolvedFinalArity,
hasDoBlockOrKeyword,
name,
canonicalNameSet
);
@NotNull Deserialized deserialized) {
super(parent, elementType, deserialized);
}

public MatchedDotCall(
Expand Down
22 changes: 3 additions & 19 deletions src/org/elixir_lang/psi/stub/MatchedQualifiedNoArgumentsCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,20 @@

import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.elixir_lang.psi.ElixirMatchedQualifiedNoArgumentsCall;
import org.elixir_lang.psi.stub.call.Deserialized;
import org.elixir_lang.psi.stub.call.Stub;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Set;

public class MatchedQualifiedNoArgumentsCall extends Stub<ElixirMatchedQualifiedNoArgumentsCall> {
public MatchedQualifiedNoArgumentsCall(
StubElement parent,
@NotNull IStubElementType elementType,
@Nullable StringRef resolvedModuleName,
@Nullable StringRef resolvedFunctionName,
int resolvedFinalArity,
boolean hasDoBlockOrKeyword,
@NotNull StringRef name,
@NotNull Set<StringRef> canonicalNameSet
) {
super(
parent,
elementType,
resolvedModuleName,
resolvedFunctionName,
resolvedFinalArity,
hasDoBlockOrKeyword,
name,
canonicalNameSet
);
@NotNull Deserialized deserialized) {
super(parent, elementType, deserialized);
}

public MatchedQualifiedNoArgumentsCall(
Expand Down

0 comments on commit 136af95

Please sign in to comment.